neděle 1. listopadu 2015

Jak se vyplatí kešování?

Vyplatí se kešování? Jak moc? Dá se účinnost kešování předem nějak kvantifikovat? Jak nastavit velikost a retenci keše? Na tyto a podobné otázky se pokusí odpovědět můj článek.

Před časem jsme na jednom produkčním systému - službě vracející stavy a historii zpracování balíků - zvažovali možnost konfigurace kešování. Kešovat jsme chtěli stav a historii pro daný identifikátor. Jde ale předem zjistit, jestli bude kešování účinné? Vyplatí se vůbec? Jak nastavit parametry kešování, aby bylo co nejúčinnější? Kešování nemělo být spásou pro řešení aktuálních problémů, ale jednou ze strategií, jak se připravit stabilní systém na očekávanou zvýšenou zátěž o Vánocích.

K dispozici jsme měli zkušenosti a logy za první dva týdny provozu.

Statistika


Jednoduchá statistika requestů - počty a distinct počty zásilek pro první dva týdny provozu:

datum
počet
distinct počet
% distinct (0..1)
2014-04-01
291119
119738
0,411302594
2014-04-02
283813
111442
0,392659956
2014-04-03
279593
104104
0,372341225
2014-04-04
260349
97965
0,376283373
2014-04-05
161026
50408
0,313042614
2014-04-06
153951
48013
0,311871959
2014-04-07
282551
110197
0,390007468
2014-04-08
220211
86256
0,391697054
2014-04-09
307659
109649
0,35639783
2014-04-10
313538
120067
0,382942418
2014-04-11
297510
113246
0,380646029
2014-04-12
157255
54044
0,343671107
2014-04-13
161753
58605
0,362311673

Procento unikátních čísel samo o sobě moc neříká, ale počet distinct zásilek za den dává přesnou představu, kolik by cache mohla obsahovat nejvíce záznamů. Horní odhad pro počet záznamů v keši je tak přibližně 120000.

Simulace!


Access log obsahující url každého přístupu k zásilkám nám dovoluje chování keše simulovat. Simulace znamená procházení requestů jeden po druhém a počítání, kolik by cache ušetřila.

Jednoduchá implementace simulátoru keše v Groovy:


Simulace pak prochází log a pro každou zásilku zavolá cache.intercept(parcelNumber, dateTimeRequest):


Příklad načítá záznamy access logu z databáze. Nad access logem jsme prováděli více analýz a tato transformace se nám vyplatila.

Simulace pro různé parametry keše nám dovolí konfigurace porovnat. Následující tabulka zachycuje výsledky simulace nad produkčními daty za první dva týdny běhu. Simulace běžela pro 3151282 requestů.

Retence (sekundy)
Hit count
Miss count
% hitů (0..1)
1800
570352
2580930
0,180990467
(hodina) 3600
769467
2381815
0,244175862
(něco přes hodinu) 4000
843278
2308004
0,267598393
7500
1075121
2076161
0,341169403
(1 den) 86400
2069802
1081480
0,656812688

Zjistili jsme, že ideální hodnota pro retenci keše je 4000 sekund. Pro tuto hodnotu by zahitovalo přibližně 27% requestů. Na kontextu aplikace záleží, jestli je retence "něco přes hodinu" přijatelná a jestli je to dobrý výsledek. V našem případě to dobré bylo a vyhodnotili jsme, že kešování má smysl. 

Jednoduchá implementace není bez omezení. Nezohlednila například cluster a replikace keší.

Shrnutí


Motivací pro vznik článku byla snaha odhadnout účinnost kešování ještě před jeho použitím. Simulace kešování nad reálnými daty dovoluje ověřit účinnost kešování i tam, kde už nakonfigurované je. Konfigurace kešování nemusí být střelbou od boku, ale promyšleným krokem s přesně odhadnutým očekávaným výsledkem.