Load data on demand into a cache from a data store. This pattern can improve performance and also helps to maintain consistency between data held in the cache and the data in the underlying data store.
從數據存儲區加載到緩存中的數據。這種模式可以提高性能,也有助于保持在緩存中的數據之間的一致性和底層數據存儲的數據。
Context and Problem 背景與問題
Applications use a cache to optimize repeated access to information held in a data store. However, it is usually impractical to expect that cached data will always be completely consistent with the data in the data store. Applications should implement a strategy that helps to ensure that the data in the cache is up to date as far as possible, but can also detect and handle situations that arise when the data in the cache has become stale.
應用程序使用緩存來優化重復訪問數據存儲區中的信息。然而,通常是不切實際的期望,緩存的數據將永遠是完全一致的數據存儲在數據存儲。應用程序應該實現一個策略,以確保在緩存中的數據盡可能盡可能的日期,但也可以檢測和處理的情況下,當緩存中的數據已成為過時。
Solution 解決方案
Many commercial caching systems provide read-through and write-through/write-behind operations. In these systems, an application retrieves data by referencing the cache. If the data is not in the cache, it is transparently retrieved from the data store and added to the cache. Any modifications to data held in the cache are automatically written back to the data store as well.
許多商業高速緩存系統提供read-through write-through/write-behind 等操作。在這些系統中,應用程序通過引用緩存來檢索數據。如果數據不在緩存中,則從數據存儲區中檢索到緩存,并添加到緩存中。在緩存中保存的數據的任何修改都會自動返回到數據存儲區中。
For caches that do not provide this functionality, it is the responsibility of the applications that use the cache to maintain the data in the cache.
對于不提供此功能的緩存,應用程序的責任是使用緩存來維護緩存中的數據的。
An application can emulate the functionality of read-through caching by implementing the cache-aside strategy. This strategy effectively loads data into the cache on demand. Figure 1 summarizes the steps in this process.
應用程序可以通過緩存策略來模擬讀取緩存的功能。這個策略有效地將數據加載到緩存中的需求。圖1總結了這個過程中的步驟。
Figure 1 - Using the Cache-Aside pattern to store data in the cache
圖1 -使用高速緩存模式來存儲緩存中的數據
If an application updates information, it can emulate the write-through strategy as follows:
1.Make the modification to the data store
2.Invalidate the corresponding item in the cache.
如果一個應用程序更新信息,它可以通過如下策略來實現:
1、修改的數據保存到數據區,
2,使緩存區的對應項無效。
When the item is next required, using the cache-aside strategy will cause the updated data to be retrieved from the data store and added back into the cache.
當該項是下一個需要時,使用緩存策略將導致更新的數據從數據存儲中檢索,并將其添加到緩存中。
問題和注意事項
Consider the following points when deciding how to implement this pattern:
在決定如何實現這個模式時,考慮以下幾點:
Lifetime of Cached Data:Many caches implement an expiration policy that causes data to be invalidated and removed from the cache if it is not accessed for a specified period. For cache-aside to be effective, ensure that the expiration policy matches the pattern of access for applications that use the data. Do not make the expiration period too short because this can cause applications to continually retrieve data from the data store and add it to the cache. Similarly, do not make the expiration period so long that the cached data is likely to become stale. Remember that caching is most effective for relatively static data, or data that is read frequently.
緩存數據的生命周期:許多的緩存實現過期策略導致數據失效并從緩存中移除如果不在指定時間內訪問。為了緩存到緩存中的有效性,確保過期策略匹配使用數據的應用程序的訪問模式。不要使過期時間太短,因為這可能導致應用程序不斷地從數據存儲中檢索數據,并將其添加到緩存中。同樣,不要使過期時間過長,緩存的數據可能會變得不新鮮。請記住,緩存是最有效的相對靜態的數據,或是經常讀的數據。
Evicting Data: Most caches have only a limited size compared to the data store from where the data originates, and they will evict data if necessary. Most caches adopt a least-recently-used policy for selecting items to evict, but this may be customizable. Configure the global expiration property and other properties of the cache, and the expiration property of each cached item, to help ensure that the cache is cost effective. It may not always be appropriate to apply a global eviction policy to every item in the cache. For example, if a cached item is very expensive to retrieve from the data store, it may be beneficial to retain this item in cache at the expense of more frequently accessed but less costly items.
清除數據:大多數緩存具有一個規模有限的數據存儲區,并且是認為是必要的數據。大多數緩存采用最近最少使用策略來清除項,但這是可以定制的。配置緩存的全局過期屬性和其他屬性,以及每個緩存項目的過期屬性,以幫助確保緩存的成本有效。它可能并不總是適合于全球驅逐政策的每一項在緩存。例如,如果一個緩存的項目是非常昂貴的,從數據存儲檢索,它可能是有益的保留此項目在高速緩存中的費用更頻繁訪問,但成本較低的項目。
Priming the Cache:Many solutions prepopulate the cache with the data that an application is likely to need as part of the startup processing. The Cache-Aside pattern may still be useful if some of this data expires or is evicted.
啟動緩存:許多方案預填充緩存,應用程序可能需要在啟動處理部分的數據。緩存模式還可以一邊如果這部分數據過期或是有用的是驅逐。
Consistency:Implementing the Cache-Aside pattern does not guarantee consistency between the data store and the cache. An item in the data store may be changed at any time by an external process, and this change might not be reflected in the cache until the next time the item is loaded into the cache. In a system that replicates data across data stores, this problem may become especially acute if synchronization occurs very frequently.
一致性:在緩存中,不保證數據存儲和緩存的一致性。在數據存儲區中的一個項目可以在任何時間被外部過程改變,而在下一次將該項加載到緩存中時,這種變化可能不會反映到緩存中。在整個數據存儲區復制數據的系統中,如果發生頻繁發生,這個問題可能會變得特別嚴重。
Local (In-Memory) Caching: A cache could be local to an application instance and stored in-memory. Cache-aside can be useful in this environment if an application repeatedly accesses the same data. However, a local cache is private and so different application instances could each have a copy of the same cached data. This data could quickly become inconsistent between caches, so it may be necessary to expire data held in a private cache and refresh it more frequently. In these scenarios it may be appropriate to investigate the use of a shared or a distributed caching mechanism.
本地(內存)緩存:緩存可以是本地的一個應用實例,并存儲在內存中。如果一個應用程序反復訪問相同的數據,緩存可以在該環境中有用。然而,本地緩存是私有的,所以不同的應用實例可以有一個相同的緩存數據的副本。此數據可能會迅速成為不一致的高速緩存,因此它可能是必要的過期數據舉行的私人緩存和刷新它更頻繁。在這些情況下,它可能是適當的調查使用的共享或分布式緩存機制。
When to Use this Pattern 什么時候使用這種模式
Use this pattern when:
•A cache does not provide native read-through and write-through operations.
•Resource demand is unpredictable. This pattern enables applications to load data on demand. It makes no assumptions about which data an application will require in advance.
使用此模式時:
•緩存不提供本地讀寫操作,并通過操作。
•資源需求是不可預測的。這種模式使應用程序的負載數據的需求。它不假設數據的應用程序將需要提前。
This pattern might not be suitable:
•When the cached data set is static. If the data will fit into the available cache space, prime the cache with the data on startup and apply a policy that prevents the data from expiring.
•For caching session state information in a web application hosted in a web farm. In this environment, you should avoid introducing dependencies based on client-server affinity.
這種模式可能不適合:
當緩存的數據集是靜態的。如果數據將融入現有的緩存空間,主要的緩存啟動數據和應用的政策,防止數據失效。
在一個網絡應用程序中的一個網絡應用程序中緩存會話狀態信息。在這種環境中,您應該避免引入基于客戶機-服務器親和力的依賴關系。
Example 例子
In Microsoft Azure you can use Azure Cache to create a distributed cache that can be shared by multiple instances of an application. The GetMyEntityAsync method in the following code example shows an implementation of the Cache-aside pattern based on Azure Cache. This method retrieves an object from the cache using the read-though approach.
在Microsoft Azure下,你可以使用Azure Cache來創建一個分布式緩存,可以共享的應用程序的多個實例。下面的代碼示例中的GetMyEntityAsync方法顯示緩存基于Azure Cache的實現。此方法從緩存中檢索一個對象。
An object is identified by using an integer ID as the key. The GetMyEntityAsync method generates a string value based on this key (the Azure Cache API uses strings for key values) and attempts to retrieve an item with this key from the cache. If a matching item is found, it is returned. If there is no match in the cache, the GetMyEntityAsync method retrieves the object from a data store, adds it to the cache, and then returns it (the code that actually retrieves the data from the data store has been omitted because it is data store dependent). Note that the cached item is configured to expire in order to prevent it from becoming stale if it is updated elsewhere.
一個對象是通過使用一個整數ID作為key。GetMyEntityAsync 方法生成一個字符串值作為key(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; }
Note:
The examples use the Azure Cache API to access the store and retrieve information from the cache. For more information about the Azure Cache API, see Using Microsoft Azure Cache on MSDN.
The UpdateEntityAsync method shown below demonstrates how to invalidate an object in the cache when the value is changed by the application. This is an example of a write-through approach. The code updates the original data store and then removes the cached item from the cache by calling the Remove method, specifying the key (the code for this part of the functionality has been omitted as it will be data store dependent).
下面的UpdateEntityAsync方法演示了如何使一個對象在緩存中無效,當應用程序的值改變時。這是一個用寫方法的例子。代碼更新原始數據存儲,然后通過調用刪除方法刪除緩存項目,指定密鑰(此部分的功能的代碼已被省略,因為它將數據存儲依賴)。
Note:
The order of the steps in this sequence is important. If the item is removed before the cache is updated, there is a small window of opportunity for a client application to fetch the data (because it is not found in the cache) before the item in the data store has been changed, resulting in the cache containing stale data.
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); }
Related Patterns and Guidance 相關模式和指導
The following patterns and guidance may also be relevant when implementing this pattern:
- Caching Guidance. This guidance provides additional information on how you can cache data in a cloud solution, and the issues that you should consider when you implement a cache.
- Data Consistency Primer. Cloud applications typically use data that is dispersed across data stores. Managing and maintaining data consistency in this environment can become a critical aspect of the system, particularly in terms of the concurrency and availability issues that can arise. This primer describes the issues surrounding consistency across distributed data, and summarizes how an application can implement eventual consistency to maintain the availability of data.
在實施該模式時,以下模式和指導也可能是相關的:
緩存指南。本指南提供了關于如何在云解決方案中緩存數據的附加信息,以及在執行緩存時要考慮的問題。
數據一致性。云應用程序通常使用的數據是分散在數據存儲。在這個環境中管理和維護數據的一致性可能成為系統的一個重要方面,特別是在并發性和可用性問題方面可能出現的問題。該引物描述了整個分布式數據的一致性問題,并總結了如何應用程序可以實現最終的一致性,以保持數據的可用性。
文章列表