Cache-aside '-patroonCache-Aside pattern

Gegevens op verzoek laden in een cache van een gegevensarchief.Load data on demand into a cache from a data store. Dit kan de prestaties verbeteren en helpt ook bij het handhaven van de consistentie tussen de gegevens die zijn opgeslagen in de cache en de gegevens in het onderliggende gegevensarchief.This can improve performance and also helps to maintain consistency between data held in the cache and data in the underlying data store.

Context en probleemContext and problem

Toepassingen gebruikt een cache voor herhaalde toegang tot gegevens die zijn ondergebracht in een gegevensarchief verbeteren.Applications use a cache to improve repeated access to information held in a data store. Het is echter niet praktisch kunt verwachten dat gegevens in de cache wordt altijd volledig in overeenstemming zijn met de gegevens in het gegevensarchief.However, it's impractical to expect that cached data will always be completely consistent with the data in the data store. Toepassingen moeten een strategie voor die helpt om ervoor te zorgen dat de gegevens in de cache zo actueel mogelijk worden, implementeren, maar ook detecteren en afhandelen van situaties zich voordoen wanneer de gegevens in de cache is verouderd.Applications should implement a strategy that helps to ensure that the data in the cache is as up-to-date as possible, but can also detect and handle situations that arise when the data in the cache has become stale.

OplossingSolution

Veel commerciële cachebewerkingen systemen bieden read-through en write-door middel van/schrijven-behind bewerkingen.Many commercial caching systems provide read-through and write-through/write-behind operations. In deze systemen haalt een toepassing gegevens op door te verwijzen naar de cache.In these systems, an application retrieves data by referencing the cache. Als de gegevens niet in de cache, heeft deze opgehaald uit de gegevensopslag en toegevoegd aan het cachegeheugen.If the data isn't in the cache, it's retrieved from the data store and added to the cache. Alle wijzigingen aan gegevens die zijn opgeslagen in de cache automatisch teruggeschreven naar de gegevensopslag bevindt.Any modifications to data held in the cache are automatically written back to the data store as well.

Voor caches die deze functionaliteit niet bieden, is de verantwoordelijkheid van de toepassingen die gebruikmaken van de cache te onderhouden van de gegevens.For caches that don't provide this functionality, it's the responsibility of the applications that use the cache to maintain the data.

Een toepassing kan de functionaliteit van read-through door het implementeren van de cache-aside '-strategie in worden geëmuleerd.An application can emulate the functionality of read-through caching by implementing the cache-aside strategy. Deze strategie worden gegevens geladen in de cache op aanvraag.This strategy loads data into the cache on demand. De afbeelding ziet u het Cache-aside '-patroon gebruiken voor het opslaan van gegevens in de cache.The figure illustrates using the Cache-Aside pattern to store data in the cache.

Het Cache-aside '-patroon gebruiken voor het opslaan van gegevens in de cache

Als een toepassing informatie-updates, kan deze strategie voor write-through volgen door de wijziging in het gegevensarchief en het bijbehorende item in de cache ongeldig te maken.If an application updates information, it can follow the write-through strategy by making the modification to the data store, and by invalidating the corresponding item in the cache.

Als het item vervolgens vereist is, met behulp van de strategie voor de cache-aside ', wordt de bijgewerkte gegevens worden opgehaald uit de gegevensopslag en weer toegevoegd aan de cache.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.

Problemen en overwegingenIssues and considerations

Houd rekening met de volgende punten bij het bepalen van het implementeren van dit patroon:Consider the following points when deciding how to implement this pattern:

Levensduur van de gegevens in de cache.Lifetime of cached data. Veel caches implementeren een verloopbeleid die gegevens ongeldig en worden verwijderd uit de cache als deze niet toegankelijk is voor een opgegeven periode.Many caches implement an expiration policy that invalidates data and removes it from the cache if it's not accessed for a specified period. Voor cache-aside effectief wilt maken, moet u ervoor zorgen dat het verloopbeleid overeenkomt met het patroon van toegang voor toepassingen die gebruikmaken van de gegevens.For cache-aside to be effective, ensure that the expiration policy matches the pattern of access for applications that use the data. Maak de verloopperiode te kort niet omdat hierdoor kunnen toepassingen voortdurend gegevens ophalen uit de gegevensopslag en toe te voegen aan de cache.Don't 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. Op deze manier Maak niet de verloopperiode zo lang dat de gegevens in de cache is waarschijnlijk zijn verouderd.Similarly, don't make the expiration period so long that the cached data is likely to become stale. Houd er rekening mee dat opslaan in cache is het meest effectief van relatief statische gegevens of gegevens die regelmatig worden gelezen.Remember that caching is most effective for relatively static data, or data that is read frequently.

Onbeschikbaar maken van gegevens.Evicting data. De meeste caches hebben een beperkte grootte vergeleken met het gegevensarchief waarin de gegevens afkomstig is en ze je gegevens onbeschikbaar maken indien nodig.Most caches have a limited size compared to the data store where the data originates, and they'll evict data if necessary. De meeste caches vast een minst recent gebruikte beleid voor het selecteren van items onbeschikbaar maken, maar dit kan worden aangepast.Most caches adopt a least-recently-used policy for selecting items to evict, but this might be customizable. De eigenschap globale verlopen en andere eigenschappen van de cache en de eigenschap vervaldatum van elk item in de cache om ervoor te zorgen dat de cache rendabel is configureren.Configure the global expiration property and other properties of the cache, and the expiration property of each cached item, to ensure that the cache is cost effective. Het niet altijd geschikt is voor een globale taakverwijdering-beleid toepassen op elk item in de cache.It isn't always appropriate to apply a global eviction policy to every item in the cache. Bijvoorbeeld, als een item in de cache bijzonder kostbaar om op te halen uit de gegevensopslag is, kan het nuttig zijn voor dit item in de cache ten koste van de meer items voor vaak gebruikte maar minder dure houden.For example, if a cached item is very expensive to retrieve from the data store, it can be beneficial to keep this item in the cache at the expense of more frequently accessed but less costly items.

De cache Priming.Priming the cache. Veel oplossingen vullen de cache met de gegevens die een toepassing is waarschijnlijk nodig als onderdeel van het starten van de verwerking.Many solutions prepopulate the cache with the data that an application is likely to need as part of the startup processing. Het Cache-aside '-patroon kan het nuttig zijn als een deel van deze gegevens is verlopen of onbeschikbaar wordt gemaakt.The Cache-Aside pattern can still be useful if some of this data expires or is evicted.

Consistentie.Consistency. Implementatie van de Cache-aside '-patroon garandeert consistentie tussen de gegevensopslag en de cache niet.Implementing the Cache-Aside pattern doesn't guarantee consistency between the data store and the cache. Een item in het gegevensarchief kan op elk gewenst moment worden gewijzigd door een extern proces en deze wijziging mogelijk niet weerspiegeld in de cache, totdat de volgende keer dat het item wordt geladen.An item in the data store can 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. In een systeem dat de gegevens worden gerepliceerd tussen gegevensarchieven, dit probleem kunt ernstig kan worden als synchronisatie zich regelmatig voordoet.In a system that replicates data across data stores, this problem can become serious if synchronization occurs frequently.

Lokale (in het geheugen) opslaan in cache.Local (in-memory) caching. Een cache kan worden lokaal op een toepassingsexemplaar en opgeslagen in het geheugen.A cache could be local to an application instance and stored in-memory. Cache-aside ' kan in deze omgeving nuttig zijn als een toepassing herhaaldelijk toegang heeft tot dezelfde gegevens.Cache-aside can be useful in this environment if an application repeatedly accesses the same data. Een lokale cache is echter persoonlijke en exemplaren van een andere toepassing kunnen elk moet daarom een kopie van dezelfde gegevens uit de cache.However, a local cache is private and so different application instances could each have a copy of the same cached data. Deze gegevens kan snel worden consistent zijn tussen de caches, zodat het mogelijk gegevens die zijn opgeslagen in een persoonlijke cache verlopen en vaker vernieuwen.This data could quickly become inconsistent between caches, so it might be necessary to expire data held in a private cache and refresh it more frequently. In deze scenario's, kunt u het gebruik van een gedeelde of een gedistribueerde cachemechanisme onderzoeken.In these scenarios, consider investigating the use of a shared or a distributed caching mechanism.

Het gebruik van dit patroonWhen to use this pattern

Gebruik dit patroon wanneer:Use this pattern when:

  • Een cache biedt geen systeemeigen read-through en write-through bewerkingen.A cache doesn't provide native read-through and write-through operations.
  • Resource-aanvraag is onvoorspelbaar.Resource demand is unpredictable. Dit patroon kan toepassingen gegevens op verzoek laden.This pattern enables applications to load data on demand. Er wordt geen veronderstellingen over welke gegevens een toepassing vooraf is vereist.It makes no assumptions about which data an application will require in advance.

Dit patroon is mogelijk niet geschikt:This pattern might not be suitable:

  • Wanneer de gegevensset in de cache is statisch.When the cached data set is static. Als de gegevens in de cacheruimte beschikbaar wordt passen, bewerken van de cache met de gegevens bij het opstarten en toepassen van een beleid dat verhindert dat de gegevens verloopt.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.
  • Voor het opslaan van sessiestatusgegevens in een webtoepassing die wordt gehost in een webfarm.For caching session state information in a web application hosted in a web farm. In deze omgeving moet u de introductie van afhankelijkheden op basis van client / server-affiniteit niet.In this environment, you should avoid introducing dependencies based on client-server affinity.

VoorbeeldExample

U kunt Azure Redis-Cache gebruiken om een gedistribueerde cache die kan worden gedeeld door meerdere exemplaren van een toepassing te maken in Microsoft Azure.In Microsoft Azure you can use Azure Redis Cache to create a distributed cache that can be shared by multiple instances of an application.

Voor verbinding met een Azure Redis-Cache-exemplaar, roept u de statische Connect methode en geeft u de verbindingsreeks.To connect to an Azure Redis Cache instance, call the static Connect method and pass in the connection string. De methode retourneert een ConnectionMultiplexer die staat voor de verbinding.The method returns a ConnectionMultiplexer that represents the connection. U kunt een exemplaar van ConnectionMultiplexer in uw toepassing delen door een statische eigenschap in te stellen die een verbonden exemplaar retourneert, zoals in het volgende voorbeeld.One approach to sharing a ConnectionMultiplexer instance in your application is to have a static property that returns a connected instance, similar to the following example. Deze aanpak geeft u een thread-veilige manier worden slechts één verbonden exemplaar geïnitialiseerd.This approach provides a thread-safe way to initialize only a single connected instance.

private static ConnectionMultiplexer Connection;

// Redis Connection string info
private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
    string cacheConnection = ConfigurationManager.AppSettings["CacheConnection"].ToString();
    return ConnectionMultiplexer.Connect(cacheConnection);
});

public static ConnectionMultiplexer Connection => lazyConnection.Value;

De GetMyEntityAsync methode in het volgende codevoorbeeld toont een implementatie van de Cache-aside '-patroon op basis van Azure Redis-Cache.The GetMyEntityAsync method in the following code example shows an implementation of the Cache-Aside pattern based on Azure Redis Cache. Deze methode wordt een object opgehaald uit de cache met behulp van de lezen-al-methode.This method retrieves an object from the cache using the read-though approach.

Een object wordt aangeduid met behulp van een integer-ID als de sleutel.An object is identified by using an integer ID as the key. De GetMyEntityAsync methode probeert op te halen van een item met deze sleutel uit de cache.The GetMyEntityAsync method tries to retrieve an item with this key from the cache. Als een overeenkomend item wordt gevonden, is het geretourneerd.If a matching item is found, it's returned. Als er geen overeenkomst in de cache, de GetMyEntityAsync methode haalt het object van een gegevensarchief, voegt het toe aan de cache en vervolgens als resultaat gegeven.If there's no match in the cache, the GetMyEntityAsync method retrieves the object from a data store, adds it to the cache, and then returns it. De code die daadwerkelijk de gegevens van het gegevensarchief leest is hier niet weergegeven omdat deze afhankelijk van het gegevensarchief is.The code that actually reads the data from the data store is not shown here, because it depends on the data store. Houd er rekening mee dat het item in de cache is geconfigureerd om te voorkomen dat het verouderd indien elders geüpdatet is verlopen.Note that the cached item is configured to expire to prevent it from becoming stale if it's updated elsewhere.

// Set five minute expiration as a default
private const double DefaultExpirationTimeInMinutes = 5.0;

public async Task<MyEntity> GetMyEntityAsync(int id)
{
  // Define a unique key for this method and its parameters.
  var key = $"MyEntity:{id}";
  var cache = Connection.GetDatabase();

  // Try to get the entity from the cache.
  var json = await cache.StringGetAsync(key).ConfigureAwait(false);
  var value = string.IsNullOrWhiteSpace(json) 
                ? default(MyEntity) 
                : JsonConvert.DeserializeObject<MyEntity>(json);

  if (value == null) // Cache miss
  {
    // If there's a cache miss, get the entity from the original store and cache it.
    // Code has been omitted because it's data store dependent.  
    value = ...;

    // Avoid caching a null value.
    if (value != null)
    {
      // Put the item in the cache with a custom expiration time that 
      // depends on how critical it is to have stale data.
      await cache.StringSetAsync(key, JsonConvert.SerializeObject(value)).ConfigureAwait(false);
      await cache.KeyExpireAsync(key, TimeSpan.FromMinutes(DefaultExpirationTimeInMinutes)).ConfigureAwait(false);
    }
  }

  return value;
}

De voorbeelden gebruiken de API van Azure Redis-Cache voor toegang tot de store en gegevens ophalen uit de cache.The examples use the Azure Redis Cache API to access the store and retrieve information from the cache. Zie voor meer informatie met behulp van Microsoft Azure Redis-Cache en het maken van een Web-App met Redis-CacheFor more information, see Using Microsoft Azure Redis Cache and How to create a Web App with Redis Cache

De UpdateEntityAsync methode hieronder laat zien hoe u een object in de cache ongeldig te maken wanneer de waarde is gewijzigd door de toepassing.The UpdateEntityAsync method shown below demonstrates how to invalidate an object in the cache when the value is changed by the application. De code het oorspronkelijke gegevensarchief updates en verwijdert vervolgens het item in de cache van de cache.The code updates the original data store and then removes the cached item from the cache.

public async Task UpdateEntityAsync(MyEntity entity)
{
    // Update the object in the original data store.
    await this.store.UpdateEntityAsync(entity).ConfigureAwait(false); 

    // Invalidate the current cache object.
    var cache = Connection.GetDatabase();
    var id = entity.Id;
    var key = $"MyEntity:{id}"; // The key for the cached object.
    await cache.KeyDeleteAsync(key).ConfigureAwait(false); // Delete this key from the cache.
}

Notitie

De volgorde van de stappen is belangrijk.The order of the steps is important. Bijwerken van het gegevensarchief voordat het item verwijderen uit de cache.Update the data store before removing the item from the cache. Als u het item in de cache eerst verwijdert, is er een kleine venster tijd wanneer een client het item ophalen kan voordat het gegevensarchief is bijgewerkt.If you remove the cached item first, there is a small window of time when a client might fetch the item before the data store is updated. Die resulteert in een cache ontbreekt (omdat het item is verwijderd uit de cache), waardoor de eerdere versie van het item dat moet worden opgehaald uit de gegevensopslag en weer toegevoegd aan de cache.That will result in a cache miss (because the item was removed from the cache), causing the earlier version of the item to be fetched from the data store and added back into the cache. Het resultaat is verlopen cache-gegevens.The result will be stale cache data.

De volgende informatie kan worden relevante bij het implementeren van dit patroon:The following information may be relevant when implementing this pattern:

  • Opslaan in cache richtlijnen.Caching Guidance. Bevat aanvullende informatie over hoe u gegevens in een cloudoplossing en de problemen die u moet overwegen wanneer u een cache implementeren in cache.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.

  • Gegevens consistentie Primer.Data Consistency Primer. Cloud-toepassingen gebruiken doorgaans gegevens die zijn verdeeld in de gegevensarchieven.Cloud applications typically use data that's spread across data stores. Beheer en onderhoud van de consistentie van de gegevens in deze omgeving is een kritieke aspect van het systeem, met name de gelijktijdigheid van taken en problemen die zich kunnen voordoen met de beschikbaarheid.Managing and maintaining data consistency in this environment is a critical aspect of the system, particularly the concurrency and availability issues that can arise. Deze handleiding wordt aandacht besteed aan consistentie tussen gedistribueerde gegevens en bevat een overzicht van hoe een toepassing kunt implementeren met uiteindelijke consistentie voor het onderhouden van de beschikbaarheid van gegevens.This primer describes issues about consistency across distributed data, and summarizes how an application can implement eventual consistency to maintain the availability of data.