Slovník pojmů
Invalidace cache
Cache zrychluje čtení, invalidace určuje její hranici správnosti. Je to vědomá vazba mezi změnou zdroje, odvozeným pohledem a přijatelným zpožděním.
Stručná definice
Zneplatnění uloženého pohledu po změně dat.
Cache obsahuje kopii výsledku, ne autoritativní data. Invalidace zajistí, že kopie nebude používaná poté, co se změnil produkt, cena, překlad, oprávnění nebo jiný vstup, z něhož vznikla. Může znamenat smazání konkrétního klíče, zvýšení verze v názvu klíče, vypršení TTL nebo přepnutí na nově připravený cache namespace.
Neexistuje jedna správná politika pro všechny hodnoty. Veřejný katalog snese několik minut zpoždění, zatímco potvrzení zásoby nebo přístupové oprávnění musí při rozhodnutí pracovat s aktuálním zdrojem. Cílem není mít cache za každou cenu dokonale čerstvou; cílem je přesně pojmenovat, kde je starší hodnota přijatelná a co se stane při změně či chybě.
K čemu se používá
Udržení rychlého čtení bez tichého vracení starých informací
Invalidace patří ke každému měnitelnému cacheovanému pohledu.
- změna názvu, ceny, dostupnosti nebo obrázku produktu v e-shopovém katalogu
- zrušení nebo změna oprávnění uživatele, pokud cache obsahuje odvozený přístupový pohled
- obnova odpovědi externí integrace po zpracování webhooku či importu
- nahrazení serializovaného formátu při nasazení nové verze aplikace
- přepnutí indexu, konfigurace nebo překladu bez ručního mazání neznámého množství klíčů
Praktický příklad
Změna ceny produktu v několika cacheovaných pohledech
Administrátor změní cenu produktu. Databázová transakce zapíše novou cenu a do outboxu uloží událost ProductPriceChanged. Worker následně odstraní klíč detailu produktu a zvýší verzi katalogu pro daný obchod. Další návštěva detailu jej načte z databáze, zatímco seznamy produktů postupně čtou namespace s novou verzí.
Událost může přijít dvakrát nebo po retry; operace proto musí být bezpečná při opakování. Kdyby worker zrovna neběžel, TTL starých položek omezuje dobu rozporu. Aplikace současně nepoužívá tento katalogový pohled pro dokončení platby či rezervaci zásoby, kde je nutné ověřit aktuální transakční data.
$this->connection->transactional(function () use ($productId, $price): void {
$this->productRepository->changePrice($productId, $price);
$this->outbox->record(new ProductPriceChanged($productId));
});
// Worker: opakované provedení je v pořádku.
$this->cache->delete(sprintf('product:v3:%s', $productId));
$this->cacheVersion->increment('catalog:store:cz');
Jak funguje
Změna zdroje a zneplatnění pohledu mají být jeden sledovaný proces
Bezpečný tok nejdříve potvrdí business změnu ve zdroji pravdy. Teprve potom uvolní nebo označí hodnoty, které z ní vycházely.
- Transakční změna Aplikace uloží cenu, stav či jiný business údaj do autoritativní databáze. Pokud změna neprojde, nesmí se cache tvářit jako nová.
- Zjištění dopadu Návrh určí, které pohledy změna ovlivní: detail produktu, seznam kategorie, výsledek hledání, HTTP odpověď nebo agregovaný přehled.
- Invalidace nebo nová verze Aplikace smaže konkrétní klíče, zneplatní tag, zapíše novou verzi namespace nebo odešle událost workeru. Volba závisí na rozsahu a spolehlivosti.
- Další čtení Následující request najde miss, nebo už čte klíč s novou verzí. Vytvoří aktuální pohled ze zdroje a uloží jej s definovanou platností.
- Kontrola a obnova Metriky ukážou nárůst miss a dobu regenerace. Při chybě mezi databází a cache musí existovat retry, reconciliation nebo bezpečný TTL fallback.
Hlavní postupy
Mazání, TTL a verzování řeší jiný druh závislosti.
Výběr mechanismu závisí na rozsahu změny a znalosti ovlivněných klíčů.
TTL jako bezpečnostní síť
Expirace automaticky omezuje, jak dlouho může klíč přežít i při ztracené invalidaci. Sama však nezaručí okamžitou změnu a stejné TTL pro všechny hodnoty obvykle nedává smysl.
Přesné smazání klíče
Pokud známe klíč detailu produktu, může aplikace jej po změně odstranit. Je jednoduché a přesné, ale nestačí, pokud jeden produkt ovlivňuje tisíce katalogových pohledů.
Tagy a závislosti
Tag nebo skupina dovolí vyřadit více hodnot, například vše závislé na produktu či kategorii. Vyžaduje disciplinované přidávání tagů a pozornost k ceně hromadného mazání.
Verzování namespace
Klíč může obsahovat verzi katalogu či formátu. Zvýšení verze okamžitě odvede nová čtení od starých klíčů; ty staré zmizí později přes TTL. Hodí se pro široké změny a deployment.
Asynchronní invalidace
Událost ProductChanged může vyčistit hledání nebo CDN mimo databázovou transakci. Musí být doručitelná, opakovatelná a schopná dohnat ztracený krok, jinak vznikají trvalé rozdíly.
Vztah k ostatním pojmům
Invalidace propojuje cache se změnou dat, ne se samotným requestem.
Nejčastější chyby vznikají, když má každá vrstva jinou představu o tom, co je aktuální a kdo je vlastníkem změny.
- Redis
- Redis poskytuje klíče, TTL a atomické operace, ale sám neví, které business změny mají konkrétní hodnotu vyřadit.
- PostgreSQL
- Transakce v databázi potvrzuje autoritativní stav. Invalidace se nesmí tvářit jako úspěšná business změna, když transakce selhala.
- Fronta zpráv a retry
- Široké invalidace lze provést asynchronně. Událost musí snést opakované doručení a systém musí poznat, že cache ještě nedohnala změnu.
- nginx a HTTP cache
- Aplikační invalidace nemusí automaticky vyprázdnit reverse proxy nebo CDN. Pro každou vrstvu je nutné určit vlastní cache klíč a purge či TTL pravidlo.
Výhody a omezení
Přesnější aktuálnost stojí více návrhu a provozních vazeb.
Přínosy
- rychlý pohled zůstává použitelný i po změně zdrojových dat
- verzování umožní bezpečně vyměnit formát nebo široký dataset
- TTL omezuje dobu dopadu ztracené události či chyby invalidace
- sledovatelná událost oddělí transakční zápis od náročné regenerace cache
Rizika a chyby
- smazání jen detailu produktu ponechá starou cenu v kategorii, hledání či CDN
- invalidace před potvrzením databázové transakce může vyvolat regeneraci ze starých dat
- globální flush při každé drobné změně zruší přínos cache a může přetížit zdroj
- asynchronní událost bez retry a kontroly trvale rozjede cache a zdroj pravdy
- bez omezení souběhu regeneruje stejnou drahou hodnotu mnoho requestů najednou
Hranice použití
Nejdříve určit přijatelné stáří informace, potom zvolit mechanismus.
U často měněného katalogu může detail produktu používat krátké TTL a přesnou invalidaci, zatímco facety se obnoví asynchronně. Pro velký reindex nebo změnu serializace je praktičtější verze namespace než hledání každého historického klíče. Návrh má pojmenovat maximální přijatelné zpoždění každého pohledu.
Kritický zápis, například odečtení zásoby nebo povolení refundace, nemá čekat na to, až se invaliduje cache. Konečnou kontrolu provede proti aktuálním datům v transakci. Cache může zlepšit uživatelské čtení, ale nemá být součástí jediného důkazu, že business operace smí nastat.
Na co myslet
Změnu, klíče a chování při selhání je potřeba propojit testem.
Dobrý návrh dokáže ukázat, co se vyřadí po změně jednoho produktu a co se stane, když je cache backend nebo fronta nedostupná.
- zapisovat invalidaci až po úspěšném potvrzení business změny, případně použít outbox pro spolehlivé předání události
- popsat všechny pohledy závislé na jednom zdroji dat, nejen první nalezený cache klíč
- kombinovat aktivní invalidaci s TTL jako pojistkou proti ztracenému kroku
- pro velké skupiny klíčů používat verzování nebo promyšlené tagy místo neřízeného globálního flush
- měřit miss po invalidaci, délku regenerace, chybovost workeru a stáří hodnot
- testovat duplicitní událost, výpadek cache i závod mezi zápisem a souběžným čtením
Časté otázky
Jak se vyhnout tichému zastarání dat
Je TTL totéž co invalidace?
Ne. TTL automaticky omezí stáří hodnoty, ale nereaguje hned na konkrétní business změnu. Invalidace cíleně zneplatní pohled po známé změně; TTL je často pojistka, když tento krok selže.
Je nejlepší po změně vše vymazat?
Obvykle ne. Globální flush způsobí velký nárůst miss a zatížení zdroje. Lepší je určit konkrétní klíče, tag nebo verzi pohledu, který změna skutečně ovlivnila.
Musí invalidace proběhnout uvnitř databázové transakce?
Nemá se provést před jejím úspěšným potvrzením. Pro spolehlivé asynchronní předání se často používá outbox, který je uložený ve stejné transakci jako business změna.
Může se cache po změně krátce lišit od databáze?
Ano, pokud návrh vědomě připouští eventual consistency. Musí být určena maximální doba, způsob dohánění a místa, kde se pro kritické rozhodnutí cache vůbec nepoužije.
Jak řeším provozní konzistenci
Zrychlení čtení propojuji s událostmi, retry a zdrojem pravdy.
U e-commerce a integračních aplikací navrhuji cacheované pohledy tak, aby změna dat měla jasný dopad, bezpečné opakování a dohledatelnou cestu obnovy.