Model doplňování mezipaměti

Azure Cache for Redis

Na vyžádání načte data z úložiště dat do mezipaměti. To může zlepšit výkon a také pomoct se zachováním konzistence mezi daty drženými v mezipaměti a daty v základním úložišti.

Kontext a problém

Aplikace využívají mezipaměť ke zlepšení opakovaného přístupu k informacím uloženým v datovém úložišti. Není však vhodné očekávat, že data uložená v mezipaměti budou vždy zcela konzistentní s daty v úložišti. Aplikace by měla mít implementovanou strategii, která pomáhá zajistit, aby data v mezipaměti byla co nejaktuálnější, ale která taky může rozpoznávat a řešit situace, které vznikají, když jsou data v mezipaměti zastaralá.

Řešení

Řada komerčních systémů pro ukládání do mezipaměti umožňuje operace přímého čtení a přímého zápisu / opožděného zápisu. V těchto systémech aplikace načte data odkazováním na mezipaměť. Pokud data v mezipaměti nejsou, načtou se z úložiště dat a přidají se do mezipaměti. Všechny úpravy dat v mezipaměti se automaticky zapíší zpět do úložiště dat.

V případě mezipamětí, které tuto funkci nemají, jsou za správu dat zodpovědné aplikace, které mezipaměť používají.

Aplikace můžou emulovat funkci přímého čtení z mezipaměti implementací strategie doplňování mezipaměti. Tato strategie načte data do mezipaměti na vyžádání. Obrázek znázorňuje ukládání dat do mezipaměti pomocí modelu Doplňování mezipaměti.

Ukládání dat do mezipaměti pomocí modelu Doplňování mezipaměti

Pokud aplikace aktualizuje informace, může postupovat podle strategie přímého zápisu tím, že provede změnu v úložišti dat a zneplatní odpovídající položku v mezipaměti.

Jakmile bude položka příště vyžadovaná, použití strategie doplňování mezipaměti způsobí načtení aktualizovaných dat z úložiště dat a jejich přidání zpět do mezipaměti.

Problémy a důležité informace

Když se budete rozhodovat, jak tento model implementovat, měli byste vzít v úvahu následující skutečnosti:

Doba platnosti dat uložených v mezipaměti. Řada mezipamětí má implementovanou zásadu vypršení platnosti, která zneplatní data a odstraní je z mezipaměti, pokud k nim po zadanou dobu neproběhne žádný přístup. Aby bylo doplňování mezipaměti účinné, zajistěte, že zásada vypršení platnosti odpovídá modelu přístupu aplikací, které data používají. Nenastavujte dobu vypršení platnosti příliš krátkou, protože by to mohlo mít za následek to, že aplikace budou průběžně načítat data z úložiště dat a přidávat je do mezipaměti. Stejně tak nenastavujte dobu vypršení platnosti tak dlouhou, aby se data uložená v mezipaměti stala zastaralými. Mějte na paměti, že ukládání do mezipaměti je nejúčinnější pro relativně statická data nebo data, která jsou často načítaná.

Vyřazení dat. Většina mezipaměti má v porovnání s úložištěm dat, odkud data pochází, omezenou velikost a v případě potřeby data vyřadí. Většina mezipamětí používá k výběru dat k vyřazení zásadu nejméně používaných dat v poslední době, ale tato zásada může být přizpůsobitelná. Abyste zajistili, že mezipaměť bude z hlediska nákladů efektivní, nakonfigurujte u mezipaměti globální vlastnost vypršení platnosti a další vlastnosti a u každé položky uložené v mezipaměti vlastnost vypršení platnosti. Není vždy vhodné použít globální zásadu vyřazení pro každou položku v mezipaměti. Například pokud je položku v mezipaměti drahé načíst z úložiště dat, může být výhodné ponechat ji v mezipaměti na úkor častěji načítaných, ale levnějších položek.

Příprava mezipaměti. Mnoho řešení předvyplní mezipaměť daty, které aplikace bude pravděpodobně potřebovat jako součást počátečního zpracování. Doplňování mezipaměti může být přesto užitečné, pokud u některých z těchto dat vyprší platnost nebo dojde k jejich vyřazení.

Konzistence. Implementace modulu Doplňování mezipaměti nezaručuje konzistenci mezi úložištěm dat a mezipamětí. Položky v úložišti dat může kdykoli změnit externí proces a tato změna se může v mezipaměti projevit až při příštím načtení položky. V systému, který replikuje data mezi úložišti dat, se může jednat o vážný problém, pokud k synchronizaci dochází často.

Místní ukládání do mezipaměti (v paměti). Mezipaměť může být pro instanci aplikace místní a uložená v paměti. V tomto prostředí může být model Doplňování mezipaměti užitečný, pokud aplikace opakovaně přistupuje ke stejným datům. Místní mezipaměť je však soukromá, takže různé instance aplikace můžou mít kopii stejných dat uložených v mezipaměti. Tato data můžou být zanedlouho mezi jednotlivými mezipamětmi nekonzistentní, takže pravděpodobně bude nutné častěji nechat vypršet platnost dat v soukromé mezipaměti a obnovovat je. V těchto scénářích zvažte použití sdíleného nebo distribuovaného mechanismu ukládání do mezipaměti.

Kdy se má tento model použít

Tento model použijte v těchto případech:

  • Mezipaměť neposkytuje nativní operace přímého čtení a zápisu.
  • Požadavky na prostředky jsou nepředvídatelné. Tento model umožňuje aplikacím načítat data na vyžádání. Model nepředpokládá, která data bude aplikace potřebovat předem.

Tento model nebude pravděpodobně vhodný v následujících případech:

  • Sada dat v mezipaměti je statická. Pokud se data vejdou do dostupného prostoru v mezipaměti, naplňte mezipaměť daty při spuštění a použijte zásadu, která zabrání vypršení platnosti dat.
  • Pro ukládání informací o stavu relace do mezipaměti ve webové aplikaci hostovaná ve webové farmě. V tomto prostředí byste se měli vyhnout vzniku závislostí podle vztahu klient-server.

Návrh úloh

Architekt by měl vyhodnotit způsob použití modelu doplňování mezipaměti v návrhu úlohy k řešení cílů a principů popsaných v pilířích architektury Azure Well-Architected Framework. Příklad:

Pilíř Jak tento model podporuje cíle pilíře
Rozhodnutí o návrhu spolehlivosti pomáhají vaší úloze stát se odolnou proti selhání a zajistit, aby se po selhání obnovila do plně funkčního stavu. Ukládání do mezipaměti vytváří replikaci dat a v omezeném rozsahu je možné použít k zachování dostupnosti často používaných dat, pokud je úložiště dat původu dočasně nedostupné. Kromě toho, pokud v mezipaměti dojde k selhání, může se úloha vrátit do původního úložiště dat.

- RE:05 Redundance
Efektivita výkonu pomáhá vaší úloze efektivně splňovat požadavky prostřednictvím optimalizací škálování, dat a kódu. Lepší výkon ve vaší úloze je možné získat při použití mezipaměti pro data s velkými nároky na čtení, která se často nemění, a vaše úloha je navržená tak, aby tolerovala určitou nestarost.

- Výkon dat PE:08
- PE:12 Průběžná optimalizace výkonu

Stejně jako u jakéhokoli rozhodnutí o návrhu zvažte jakékoli kompromisy proti cílům ostatních pilířů, které by mohly být s tímto vzorem zavedeny.

Příklad

V Microsoft Azure můžete pomocí služby Azure Cache for Redis vytvořit distribuovanou mezipaměť, kterou může sdílet více instancí aplikace.

Následující příklad kódu používá klienta StackExchange.Redis , což je klient Redis napsaná pro .NET. Pokud se chcete připojit k instanci Azure Cache for Redis, zavolejte statickou ConnectionMultiplexer.Connect metodu a předejte připojovací řetězec. Metoda vrátí ConnectionMultiplexer představující připojení. Jeden ze způsobů sdílení instance ConnectionMultiplexer v aplikaci je pomocí statické vlastnosti, která vrací připojenou instanci, podobně jako v následujícím příkladu. Tento přístup poskytuje způsob inicializace jedné připojené instance, který je bezpečný pro přístup z více vláken.

private static ConnectionMultiplexer Connection;

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

public static ConnectionMultiplexer Connection => lazyConnection.Value;

Metoda GetMyEntityAsync v následujícím příkladu kódu ukazuje implementaci modelu Cache-Aside. Tato metoda načte objekt z mezipaměti pomocí přístupu pro čtení.

Objekt je identifikovaný pomocí celočíselného ID, který se použije jako klíč. Metoda GetMyEntityAsync se pokusí načíst položku s tímto klíčem z mezipaměti. Pokud je nalezena odpovídající položka, načte se. Pokud v mezipaměti není nalezena žádná shoda, metoda GetMyEntityAsync načte objekt z úložiště dat, přidá jej do mezipaměti a pak jej vrátí. Kód, který načítá data z úložiště dat, tady není ukázaný, protože se liší podle úložiště. Mějte na paměti, že položka uložená v mezipaměti má nakonfigurované vypršení platnosti, aby se v případě, že bude někde jinde aktualizována, nestala zastaralou.

// 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 is 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;
}

Příklady používají Azure Cache for Redis pro přístup k úložišti a načítání informací z mezipaměti. Další informace najdete v tématu Použití služby Azure Cache for Redis a vytvoření webové aplikace se službou Azure Cache for Redis.

Metoda UpdateEntityAsync níže ukazuje, jak zneplatnit objekt v mezipaměti, když aplikace změní jeho hodnotu. Kód aktualizuje původní úložiště dat a pak z mezipaměti odebere položku v ní uloženou.

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.
}

Poznámka:

Pořadí kroků je velmi důležité. Aktualizujte úložiště dat předtím, než položku odeberete z mezipaměti. Pokud nejprve odeberte položku z mezipaměti, vznikne krátké časové okno, kdy klient může načíst položku předtím, než se aktualizuje úložiště dat. Výsledkem bude neúspěšný přístup do mezipaměti (protože položka byla z mezipaměti odstraněna), který způsobí, že se z úložiště dat načte starší verze položky a přidá se zpátky do mezipaměti. Výsledkem budou zastaralá data v mezipaměti.

Při implementaci tohoto modelu můžou být relevantní následující informace:

  • Model spolehlivé webové aplikace ukazuje, jak použít model doplňování mezipaměti na webové aplikace konvergující v cloudu.

  • Pokyny k ukládání do mezipaměti. Obsahují další informace o tom, jak můžete v cloudovém řešení ukládat data do mezipaměti a o problémech, které byste měli při implementaci mezipaměti zvážit.

  • Úvod do konzistence dat. Cloudové aplikace obvykle používají data, která se nacházejí ve více úložištích dat. Správa a údržba konzistence dat v takovém prostředí je nesmírně důležitý aspekt systému, zejména problémy souběžnosti a dostupnosti, které můžou nastat. Tento úvod popisuje problémy s konzistencí napříč distribuovanými daty a shrnuje, jak aplikace může implementovat případnou konzistenci a zachovat dostupnost dat.