In our first installment of this series, we examined how Web server caching is implemented. Caching stores critical pieces of information in memory or on a local hard drive for subsequent rapid retrieval. In this installment, we’ll look at how Web application environments can use application caching to reduce load and increase performance.
What is Application Caching?
Application caching stores calculated components in memory for future use, either by the same user or multiple users. Because of the complex architecture of modern Web applications, application caching can produce huge gains in Web site response times.
A Web application is usually comprised of multiple architectural layers. At the simplest level, Web applications consist of the client, which runs the application (usually a series of HTML pages and associated technology); and the server, which processes data and generates output. When we zoom in on the server side, however, we find that most non-trivial applications consist of several additional layers. Typically, these layers include the UI layer, which generates the user interface (usually HTML); the business logic layer, which implements business rules; and the data layer, which stores and retrieves data from one or multiple data sources.
If we were to look at an online bookstore, these layers would break down as follows.
- UI Layer: The browsing and shopping cart interface shown to the users.
- Business Logic Layer: All rules pertaining to processing orders – calculating sales tax and shipping, combining and splitting orders, gift orders, tracking shipments, etc.
- Data Layer: The catalog of books, record of orders, and order workflow storage.
Obviously, this bookstore is highly dynamic: the server must generate a slightly different interface for each user based on the user’s account preferences and current shopping activity. Exchanging data between these layers and generating every component required for every request decreases site response times. Not every component, however, needs to be generated fresh every time. For example, each Web page may have its header and footer broken out into static components that can be cached by the application. The shopping site may also elect to cache dynamically generated data that change infrequently, such as selection lists of current shipping rates. Even the user’s current shopping cart status can be cached, as there is no need for the server to regenerate that data until the user invalidates it by changing the contents of her cart.
Storing components in memory for later use can represent a huge performance savings for the application, as it reduces database retrieval requests, numeric calculations, and string concatenation operations.
Considerations in Caching
Most application caching takes place on the server side. When caching data on the server, applications must balance a number of factors:
- Scope. Who can reuse the cached component? Some components, such as shopping cart content, may be specific to the current user. Other components, such as a list of shipping rates, may be global, and can be placed in a memory pool shared by all server connections.For global components, applications that run in distributed server environments must implement a caching mechanism that can be accessed across multiple Web servers. This can be accomplished either through some centralized cache (such as a Web Service that accesses a common data set), or by synchronizing the cache across all servers.
- Server Resources. Cached data reduces both processing and disk access time at the expense of system memory. Application caches require a mechanism to scavenge items out of the cache should memory become scarce. Applications must also take care not to exhaust system memory themselves through aggressive caching.
- Invalidation and Expiration. Just as with server and client resource caching, application caching requires a mechanism to invalidate a cached item. Applications can assign expiration times to these components, just as Web servers do with files served over HTTP. Alternatively, components can be expired in response to an event, such as a database update or user action. In our shopping cart example, the user’s shopping cart component can be expired whenever the user modifies her cart.
Application Caching from Server Applications
Application caching in modern Web applications is handled programmatically, and differs greatly based upon the application environment used. Most server-side application platforms offer a built-in caching library. In ASP.NET, the Cache class provides a facility for caching data and setting expiration conditions. The class also supports supplying a connection string so that data can be shared across multiple servers. Similar caching frameworks exist for other systems, including the Java Caching System (JCS) for Java (http://jakarta.apache.org/jcs/) and the Alternative PHP Cache (APC) for PHP (http://php.net/manual/en/book.apc.php).
The Danger of Application Caching
While application caching can yield enormous benefits, it can also hide severe performance problems. Development teams should load test the performance of their applications prior to implementing any caching scheme to isolate performance bottlenecks. It’s a good idea to implement targeted caching only after other performance issues introduced by inefficient algorithms and redundant data queries have been remedied.
We’ve covered Web server caching, browser caching, and application caching – but we’re not done yet! In our next installment, we’ll see how database caching can be used to eek out additional performance.