Memcached - efektivní SLABy - final
Jak jsem psal minule o dofukování dat pro memcached musel jsem svůj algoritmus vylepšit. Neprve nechám ukládaná data projít nejmenší možnou kompresí, abych zjistil, kolik dat se ukládá. A od toho se odrazím a data dofouknu. Funguje to celkem dobře. Komprese Memcached je jiná, ale liší se to do 15% a s tím už jde pracovat.
Ukázka dofouknutí:
$test_comprese=strlen(gzcompress($data, 1));
if($test_comprese<1800){$data2=lorem_ipsum(1800-$test_comprese);}//pridat na velikosti aby spadnul do SLAB 1900 bytes
A už to skutečně funguje na 1-.
těchto 9 červených SLABů se po restartu cache už znovu nevytvoří a ušetří to 9MB v RAM
Nakonec je tohle lepší řešení než navyšovat hodnotu f tj násobek SLABů. Po hodnotě 5,8kBytes už nemám problém SLABy využít na 100% a každý další násobek by bral hodně místa.
7,3kB má kapacitu 141 položek
9,1kB má kapacitu 112 položek
11,4kB má kapacitu 90 položek
Kdybych tedy vynechal první dva uvedené SLABy a všechno chtěl uložit až do 11,4kB potřeboval bych kapacitu 141 + 112 = 253 míst tj 253/90 = 2,8x vyššího SLABu místo 2. Navýšení dat skoro 30%. V tomto případě by to vyšlo hůř o (141 + 2352)/90 = +28MB RAM. A to už je slušná porce. Tady naopak dává smysl koeficient dát dolů na 1,1 - 1,2 a vecpat přibližně stejná data do menších šuplíků, které vzniknou, protože od velikosti 7,3kB nemám problém šuplíky plnit na 100%.
SLABy/šuplíky začínají dávat smysl pokud je dokážete zaplnit daty alespoň na 75% možná přes 50%. Nemá smysl mít SLABy ve kterých je 5% obsazeného místa, to je neefektivní. V mém případě ukládám stále stejná data (velikostně) +/- a proto to takhle optimalizuji.
Už se těším na test, kdy SLABy budu zmenšovat. SLABy velikosti 9,1 - 11,4 - 14,2 - 17,8 - 22,2 - 27,7 atd kB mají více stran. To je jasný prostor, že kdyby ta řada byla blíž u sebe mohl bych naplnit SLABy pořád přes 80% a vešlo by se do nich více dat. Do 9,1kB se vejde 112 položek a má 21 stran. Kdybych měl SLAB i 8kB vešlo by se do něj 128 položek tj +12%. Kdybych tam dostal polovinu položek z většího SLABu bylo by to o 160 dat víc při stejné zabrané paměti. A o tom to je.
A naopak: Kdybych zrušil SLAB 1,9kB a házel to až do 5,8kB měl bych tam 85+30 položek tj 115 (reálně nyní vidím 98 + 30 = 128) a kapacita 5,8kB SLABu je 176 položek. Velice bych se přiblížil hranici, kde pár dat navíc by se přehouplo k potřebě další stránky SLABu a vytvořila by si jí. Tím by zabrala 1MB místa pro pár položek. Je tedy efetivnější (nebo stejně efektivní) je mít to takhle a mít rezervu v obou SLABech (84% + 83%). Proč to najednou nevychází? Protože tyto SLABy jsou od sebe hodně daleko 1,9 vs 5,8 tj 3 násobek velikosti. A trojnásobit data v těchto velikostech už stojí dost paměti.
ušetřených 14MB cache po dalším restartu
U mě v cache 2GB to nemá takový efekt, ale malých cache v řádech desítek MB to už dobrá porce. Čím více různě dlouhá data máte, tím je to zajímavější řešení. Pokud ukládáte stejné hodnoty vytvoří se jeden slab a to je pak značka ideál.