Figure: AppFabric Caching Services speeds up access to frequently accessed data.
When the cache client first acquires some item of data, such as information supplied by the user of an ASP.NET application or values read from a database, it can use an AppFabric Caching Services client library to explicitly store this information in the cache cluster under a unique name. (As described later, ASP.NET applications can also do this transparently through the Session object, so using caching needn’t require any code changes.) To the client, all of the cache servers in the cluster appear as a single logical store—the client neither knows nor cares which physical server winds up holding the cached data. If it chooses to, the client can also store the data item in its own local cache.
When the client needs to access the same data item again, it asks for it using the item’s name. This query first checks the local cache (if one is being used). If the item is found, the client uses this cached value. If the data item isn’t in the local cache, the query is then sent to the cache cluster. If the item is found here, the client uses the value returned from the cluster. All of this is transparent to the client—it just requests the item, and AppFabric Caching Services takes care of the rest. If the item isn’t found in either the local cache or the cache cluster, the client needs to look elsewhere for the information, such as in the application database.
AppFabric Caching Services was originally code-named “Velocity”, a name that suggests exactly what the technology does: It makes repeated access to the same data faster. Rather than forcing an application to make repetitive calls to the database, it instead allows access to data directly from memory, either locally or on one of the cache servers. For applications that frequently access the same data—a large category—caching improves both performance and scalability.
AppFabric Caching Services are designed to be used by .NET applications, and so a cached data item can be any serialized .NET object. Once an object is in the cache, applications can update this cached version or explicitly delete it. Cached data items are also removed by the caching service itself, either through expiration of a configurable time-out period or by being evicted to make room for more frequently accessed information. Data items in the local cache can expire as well, and they can also be set to synchronize automatically with any changes made to the same item in the cache cluster.
Multiple cache clients can share the same cache cluster. This makes sense, since a scalable application will likely replicate its business logic (such as ASP.NET pages) across multiple machines, each of which needs to access the cache. It also raises security issues, however. To make this sharing less risky, all data sent between cache clients and cache servers can be digitally signed and encrypted, and an administrator can limit which accounts have access to each cache. Still, an organization must make sure that all clients using the same cache are trusted, since they can potentially access each other’s data.
Caching is useful with various kinds of data. For example, caching makes good sense for unchanging data that’s accessed simultaneously by multiple clients, such as catalog information for an online retailer. Another good use of caching is to store data that changes but is accessed by only one client at a time, such as the information in an ASP.NET Session object. Once again, the problem of controlling concurrent access to the cached data doesn’t arise.
But what about data that both changes and is accessed simultaneously by multiple clients? Caching can be used here as well, but life gets a little more complicated: Concurrency control is required. To address this situation, AppFabric Caching Services provides both optimistic concurrency control, based on a version number assigned to each cached object, and pessimistic concurrency control, relying on explicit locks.