cache – tagy (ne)pochopení
- Filip111
- Člen | 244
Ahoj, jak se projekt rozrůstá trochu se mi komplikuje invalidace cache.
Nepoužívám tagy a chci se zeptat jak fungují. (dokumentaci jsem četl :)
Příklad:
mám vícejazyčný katalog (třeba zboží), to je dělené do kategorií a
každá kategorie má definované svoje parametry, např. kategorie Notebooky
má definované parametry velikost HDD, velikost displeje, typ procesoru
apod.
Pokud změním kategorii, potřebuji invalidovat veškeré zboží v ní
(např. nastavím kategorii disabled),
když upravím parametry této kategorie, potřebuji zase invalidovat kategorii
a veškeré zboží v ní, když změním zboží invaliduji jen zboží, když
změním jazyk (např. disabled) invaliduji vše pro daný jazyk (kategorie,
parametry, zboží, zkrátka všechno).
Lze k tomu použít tagy, pokud ano tak takto?
cs
cs/category/$cid
cs/category/$cid/param
cs/category/$cid/goods/$gid
Když budu ukládat do cache zboží, musím mu předat všechny tyto tagy nebo stačí jen cs/category/$cid/goods/$gid a pokud invaliduji cs invalidují se všechny zanořené tagy?
(jde mi o to jestli to funguje jako stromová struktura a všechny listy předaného uzlu se invalidují nebo to jsou jen obyčejné kódy a musím otrocky všechno vyjmenovat…)
Případně máte nějaký best practice jak řešit invalidaci u podobně závislých objektů?
Díky.
- Filip Procházka
- Moderator | 4668
Tagy jsou pole stringů, žádný strom.
$cache->save($key, $value, array(
Cache::TAGS => array(
'category' . $categoryId,
'zbozi' . $zboziId,
...
)
));
A když něco změníš, pak invaliduješ tag, kterého se změna týká (zboží, kategorie, parametr, …)
PS: trošku mě děsí, co to vytváříš? Najdi si na Google termín „premature optimization“.
- Filip111
- Člen | 244
ok, přečtu si.
Taky mě to děsí – zatím hledám jak z toho ven.
Čas od času nahlídnu do topicu na který jsem se už ptal Co
ukládat a kdy invalidovat, (zatím jsem to nedokázal zprovoznit, resp.
jsem se k tomu nedokopal).
Říkám si ale, že pro uvedený příklad by mi to stejně nijak nepomohlo.
- Filip Procházka
- Moderator | 4668
Já bych to cachování nijak nehrotil. Až to bude vypadat, že web jede pomalu, pak to začni řešit :)
PS: výborné téma, v podstatě všechno už bylo řečeno tam ;)
Editoval HosipLan (2. 1. 2012 16:10)
- Filip111
- Člen | 244
Nehrotim – ale dost mě to štve. Jde o to, že mám několik kategorií ve stromové struktuře, každá kategorie má nějaké parametry. Poslední kategorie ve stromu tyto parametry dědí ze všech nadřazených kategorií.
Pokud tedy chci načíst parametry poslední kategorie, musím nejdřív
načíst strom nadřazených kategorií a pro každou navíc ještě parametry.
(a protože jsem dělal DB návrh už dávno, není to uspořádaný strom ale
musím jít rekurzí, takže se počet DB dotazů docela nastřádá)
Zkusím na to nemyslet :)
- Filip Procházka
- Moderator | 4668
Tak to je pak celkem oprávněné.
Asi bych celý strom „vytvořil“, dal si do pole IDčka všech řádků,
které v něm budou (jenom ty kategorie category1
,
category20
) a když se pak něco změní v kategorii
invalidovat.
Když už tak i cachovat se má jednoduše :)
- Filip111
- Člen | 244
Upustil jsem od nějakého většího předělání cache a jen upravuji
systém abych mohl cachovat vícejazyčné záznamy. Klíč cache je
nejakyKlic[$lang]
Narazil jsem ale na problém s invalidací – předpokládal jsem, že
když invaliduji celé pole nejakyKlic
, invalidují se všechny
záznamy tohoto pole (pro všechny jazyky)…to se ale nestalo. Musím je
invalidovat zase pomocí celého klíče nejakyKlic[$lang]
Takhle to má opravdu fungovat?
Čekal jsem chování jako u pole, ale funguje to podobně jako tagy, klíč je
zase jen pouhopouhý string.
Díky.
- Filip Procházka
- Moderator | 4668
Nehledě na to, že jsem tvůj předpoklad ani nepochopil, nebylo by to zbytečně magické? Čím víc toho cache bude umět, tím bude pomalejší a pak tak trochu ztrácí smysl něco cachovat, že.
- Filip111
- Člen | 244
V dokumentaci se píše Do cache lze ukládat jakékoliv struktury, nemusí to být jen řetězec. A totéž platí i pro klíče.
Otázka tedy zní, když použiji jako klíč pole, chová se jako pole nebo jako řetězec? To přece neni žádná magie, když je to vypíchnutý v dokumentaci. Příklad:
$this->context->cache->save('klic[0]', $text0);
$this->context->cache->save('klic[1]', $text1);
Měl by některý z následujících příkazů invalidovat oba předchozí klíče nebo ne? (podle dokumentace jsem pochopil že ano, ale v reálu k invalidaci nedojde)
$this->context->cache->save('klic[]', null);
$this->context->cache->save('klic', null);
Editoval Filip111 (3. 1. 2012 18:08)
- Filip Procházka
- Moderator | 4668
Ale hlouposti… To je přece obyčejný string!
klíč jako pole je myšleno toto
$cache = new Nette\Caching\Cache($this->context->cacheStorage, 'Categories');
$cache->save(array('klic' => 1), $data);
To je kvůli tomu, když potřebuješ složitější klíč pro cache. Když máš například spoustu parametrů
$cache->save(array('sql' => "SELECT * FROM tabulka WHERE id = ?", 'params' => array(1)), $vysledek);
Už to chápeš?
Funguje to tak, že co dáš do $key
tak prožene přes serialize a to bude výsledný klíč.
Pokud chceš ty něco invalidovat, použiješ tagy. Pokud chceš, aby se to invalidovalo samo, tak tomu nastavíš závislosti.
Editoval HosipLan (3. 1. 2012 19:07)