緩存預留模式是根據需求從數據存儲緩存加載數據。這種模式能夠提升性能,並有助於維持在基礎數據存儲在高速緩存中保持的數據和數據之間的一致性。緩存
應用程序使用的高速緩存來優化重複訪問的數據存儲中保持的信息。然而,它一般是不切實際的指望緩存的數據將始終與在數據存儲器中的數據徹底一致。應用程序要實現一種策略,有助於確保在高速緩存中的數據是最新的,只要有可能,但也能夠檢測和處理的過程當中出現,當在高速緩存中的數據已經變得陳舊的狀況。服務器
許多商業緩存系統提供通讀和直寫式/後寫操做。在這些系統中,應用程序經過引用高速緩存中檢索數據。若是數據不在緩存中,它被透明地從數據存儲中檢索並添加到高速緩存。任何修改在高速緩存中保持的數據被自動地寫入到數據存儲區以及。async
爲緩存不提供此功能,則使用該緩存保持在高速緩存中的數據的應用程序的責任。分佈式
一個應用程序能夠經過實現高速緩存預留戰略模擬的讀式高速緩存的功能。這種策略有效地將數據加載需求的高速緩存。圖 1 總結了在該過程當中的步驟。性能
圖1 - 使用Cache-除了圖案來將數據存儲在高速緩衝存儲器優化
若是一個應用程序將更新的信息,它能夠模擬通寫策略以下:this
當該項目被下一個須要,可以使用高速緩存預留策略將致使從數據存儲中檢索和從新添加到高速緩存中的更新數據。spa
在決定如何實現這個模式時,請考慮如下幾點:rest
使用這種模式時:code
這種模式可能不適合:
在微軟的 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); }