缓存预留模式是根据需求从数据存储缓存加载数据。这种模式可以提高性能,并有助于维持在基础数据存储在高速缓存中保持的数据和数据之间的一致性。
应用程序使用的高速缓存来优化重复访问的数据存储中保持的信息。
然而,它通常是不切实际的期望缓存的数据将始终与在数据存储器中的数据完全一致。应用程序要实现一种策略,有助于确保在高速缓存中的数据是最新的,只要有可能,但也可以检测和处理的过程中出现,当在高速缓存中的数据已经变得陈旧的情况。
许多商业缓存系统提供通读和直写式/后写操作。在这些系统中,应用程序通过引用高速缓存中检索数据。如果数据不在缓存中,它被透明地从数据存储中检索并添加到高速缓存。任何修改在高速缓存中保持的数据被自动地写入到数据存储区以及。
为缓存不提供此功能,则使用该缓存保持在高速缓存中的数据的应用程序的责任。
一个应用程序可以通过实现高速缓存预留战略模拟的读式高速缓存的功能。这种策略有效地将数据加载需求的高速缓存。
如果一个应用程序将更新的信息,它可以模拟通写策略如下:
当该项目被下一个需要,可使用高速缓存预留策略将导致从数据存储中检索和重新添加到高速缓存中的更新数据。
在决定如何实现这个模式时,请考虑以下几点:
使用这种模式时:
这种模式可能不适合:
在微软的 Azure,您可以使用 Azure 的缓存来创建一个分布式缓存,可以通过一个应用程序的多个实例可以共享。下面的代码示例中的 GetMyEntityAsync 方法给出了基于 Azure 的缓存 Cache 后备模式的实现。此方法从利用读虽然方法缓存中的对象。
一个目的是确定用一个整数ID作为键。该 GetMyEntityAsync 方法生成基于此键(在 Azure 缓存 API 使用的键值字符串)的字符串值,并尝试检索与从缓存中这一关键的项目。如果匹配的项目被发现,它被返回。
如果在缓存中没有匹配,则 GetMyEntityAsync 方法从一个数据存储中的对象时,把它添加到缓存中,然后将其返回(即实际上获得从数据存储中的数据的代码已经被省略,因为它是数据存储依赖)。注意,缓存项被配置以防止其成为陈旧如果是在别处更新过期。
private DataCache cache; ... public async Task<MyEntity> GetMyEntityAsync(int id) { // Define a unique key for this method and its parameters. var key = string.Format("StoreWithCache_GetAsync_{0}", id); var expiration = TimeSpan.FromMinutes(3); bool cacheException = false; try { // Try to get the entity from the cache. var cacheItem = cache.GetCacheItem(key); if (cacheItem != null) { return cacheItem.Value as MyEntity; } } catch (DataCacheException) { // If there is a cache related issue, raise an exception // and avoid using the cache for the rest of the call. cacheException = true; } // If there is a cache miss, get the entity from the original store and cache it. // Code has been omitted because it is data store dependent. var entity = ...; if (!cacheException) { try { // Avoid caching a null value. if (entity != null) { // Put the item in the cache with a custom expiration time that // depends on how critical it might be to have stale data. cache.Put(key, entity, timeout: expiration); } } catch (DataCacheException) { // If there is a cache related issue, ignore it // and just return the entity. } } return entity; }
注意:
该示例使用了 Azure 的缓存 API 来访问存储和检索的缓存信息。有关 Azure 的缓存 API 的更多信息,请参阅MSDN 上使用微软的 Azure 缓存。
下面所示的 UpdateEntityAsync 方法说明如何在高速缓存中的对象无效,当该值是由应用程序改变。这是一个写通方法的实例。该代码更新原始数据存储,然后通过调用 Remove 方法,指定键(这部分功能的代码已经被省略了,因为这将是数据存储相关)从缓存中删除缓存项
注意
在这个序列中的步骤的次序是重要的。如果之前的缓存更新的项被删除,对于客户端应用程序中的数据存储中的项目之前获取的数据(因为它没有在高速缓存中发现的)的机会已经改变一个小窗口,从而在缓存包含过期数据。
public async Task UpdateEntityAsync(MyEntity entity) { // Update the object in the original data store await this.store.UpdateEntityAsync(entity).ConfigureAwait(false); // Get the correct key for the cached object. var key = this.GetAsyncCacheKey(entity.Id); // Then, invalidate the current cache object this.cache.Remove(key); } private string GetAsyncCacheKey(int objectId) { return string.Format("StoreWithCache_GetAsync_{0}", objectId); }