Článek vyšel na blogu Jakuba Vrány, na Zdrojáku ho přetiskujeme s autorovým souhlasem.
Vysoká granularita
V keši budeme mít samostatné záznamy pro každou jednotlivou částečku, kterou chceme zpracovat:
- Celkový počet článků.
- Seznam ID článků podle zvoleného řazení.
- Nadpis, URL, perex, datum vydání a ID autora každého článku.
- Jméno a URL autora.
- URL a rozměry perexového obrázku.
- Seznam ID skupin, do kterých je článek zařazen.
- Název a URL těchto skupin.
- Celkový počet názorů každého článku.
- Počet nových názorů každého článku.
To je spousta údajů, které musíme získávat samostatně, což bude zdržovat. Některé údaje jsou navíc závislé na dříve načtených datech, takže s jejich získáním musíme počkat, až tato data budeme mít.
Nízká granularita
Často se proto přistupuje ke snížení granularity. Uložíme:
- Celkový počet článků.
- Seznam ID článků podle zvoleného řazení.
- Všechna potřebná data o každém článku, ať už strukturovaně nebo případně rovnou jako HTML kód.
- Počet nových názorů bychom z toho asi vyjmuli, protože ten bude pro každého čtenáře jiný.
Problém tohoto přístupu spočívá v tom, že pokud se cokoliv změní (např. někdo přidá názor), tak musíme keš invalidovat, případně i kaskádově. Buď tedy musíme definovat složité invalidační závislosti nebo každému záznamu nastavit platnost a po uplynutí určité doby ho obnovit, ať už se změnil nebo ne. První přístup vede k větší komplexnosti aplikace a invalidaci velkých částí keše třeba i při malé změně. Druhý přístup způsobuje zobrazování zastaralých dat a zbytečné obnovování keše, i když se data nezměnila.
Kombinovaná granularita
Oba přístupy lze zkombinovat:
- Když dojde k zneplatnění keše s nízkou granularitou, tak stále platná data získáme z keše s vysokou granularitou.
Zásadní nevýhoda tohoto přístupu spočívá v tom, že se spousta dat ukládá duplicitně.
Co si vybrat
Já jsem dříve často jako jedinou možnost zrychlení aplikace viděl snižování granularity – čím víc toho budeme ukládat a načítat pohromadě, tím to přece bude rychlejší! Náročnost invalidace keše a s tím spojená větší komplexnost aplikace ale může tuto snahu zcela zhatit. Navíc můžeme dospět k tomu, že data do keše budeme ukládat jen proto, abychom je vzápětí smazali a uložili znovu. Keš tedy paradoxně může celou aplikaci zpomalit.
Nyní se proto zásadně kloním ke kešování s vysokou granularitou. Aby mohlo dobře fungovat, je potřeba splnit tři podmínky:
- Data získávat pokud možno v atomických celcích. Vyhnout se tedy např. spojování tabulek. S tím pomáhá NotORM.
- Dotazy do keše dávkovat a provádět je ve velkých blocích. V příkladu tedy např. informace o autorovi, seznamu skupin, perexovém obrázku a počtu názorů získat během jediné komunikace s keší pro všechny tyto údaje ze všech zobrazených článků najednou. S tím pomáhá NotORM 2.
- Každý požadavek musí proběhnout v konstantním čase, i logaritmický čas (k vidění např. u stromových indexů) toto řešení diskvalifikuje. To splňuje např. Memcache nebo MEMORY tabulky v MySQL.
Ve výsledku získáme aplikaci, která je jednoduchá (neobsahuje žádné invalidační závislosti), bezchybná (nezobrazuje zastaralá data), šetrná ke zdrojům (data ukládá jen jednou) a přitom výkonnostně obvykle optimální.
Srovnání: Basecamp Next používá kombinovanou granularitu – stejná data ukládá do keše třeba čtyřikrát a např. při přidání komentáře musí všechny tyto čtyři kopie zahodit a sestavit a uložit je znovu.
Přijďte si o tomto tématu popovídat na školení Výkonnost webových aplikací.
Přehled komentářů