Rozbíjí se velká cache, která má desítky tisíc souborů a btfj.dat má desítky mega

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Ascaria
Člen | 187
+
0
-

Ahoj,

mám takový problém, dávno jsem implementoval cachování u všech modelů

<?php
    /**
     * Sets and creates cache.
     * @param String|Cache $cache cache dir or cache object
     */
    public function setCache($cache)
    {
        if($cache instanceof Cache) {
            $this->cache = $cache;
            return;
        }
        // Každá instance potomka této třídy vytvoří vlastní cache s filejournalem a s namespace jako je absolutní cesta k třídě
        $namespace = str_replace('\\', '.', get_called_class());
        $fjDir = $cache.'/_'.$namespace;
        if(!is_dir($fjDir)) {
            umask(0000);
            mkdir($fjDir, 0777, true);
        }
        $this->cache = new Cache(new FileStorage($cache, new FileJournal($fjDir)), $namespace);
        //$this->cache = new Cache(new \Nette\Caching\Storages\DevNullStorage(), $namespace);
    }
?>

Problémy začaly až teď, kdy jsem spoustu metod začal cachovat. Jeden model má například teď ve své cache složce desítky tisíc souborů a ten btfj.dat má desítky mega.

Web napíše jen:
Your browser sent a request that this server could not understand or process.

Dělá to tuším Chrome a aby to bylo zajímavější, tak jen na nějakých počítačích. Na jednom se zobrazí výpis v gridu, ale po použití stránkování to napíše tamten error, na druhém to spadne hned a žádný výpis se nezobrazí, na třetím (mém) tak různě, jednou spadne, dneska zrovna běží. Dělá to jen v části webu, kde se používá tahle velká cache.

Nesetkal se s tím už někdo? Zkoušel sem k tomu něco najít, mám podezření že to nějak malformuje ten btfj.dat, ale jinak si nevím rady.

Do cache přidávám/ mažu z ní následovně:

<?php
$this->parameters = $cache->load('facility-'.$this->idFac.'-loadParameters');
if(!is_array($this->parameters)) {
    //...
    //...
    $cache->save('facility-'.$this->idFac.'-loadParameters', $this->parameters, Array(
        Cache::TAGS => Array(
            'facility-'.$this->idFac,
            'facility-'.$this->idFac.'-parameters'
        )
    ));
}

// mazání třeba
$cache->clean(Array(
    Cache::TAGS => Array('facility-'.$this->id)
));
// nebo třeba
$cache->clean(Array(
    Cache::TAGS => Array('facility-'.$this->idFac.'-parameters')
));
?>

Verze:
PHP 5.3.10–1ubuntu3.8 | Apache/2.2.22 (Ubuntu) | Nette Framework 2.0.12 (released on 2013–08–08)

Majkl578
Moderator | 1364
+
0
-

V error logu (ať už Nette nebo serveru) nic není? Ad ta chyba prohlížeče, zkus kouknout na source odpovědi (možná bude stačit Firebug-like tool a kouknout na odpověď serveru, co vlastně poslal, příp. wget/curl a nechat si zobrazit i hlavičky).

Ascaria
Člen | 187
+
0
-

Cache byla tak velká, že při deployi jí to nedokázalo smazat celou, než na ten web někdo přistoupil, a maintenance stránka tam při deployování není. Tak jsem web vypnul, cache smazal v klidu a zdá se že to jede.

Dále v error logu právě nic není. Podařilo se mi zjistit, že v createComponent metodach vyhazuju výjimky

<?php
    protected function createComponentPhotosFromStreetViewDialog()
    {
        if(!$this->getUser()->isAllowed('Facilities:Admin:Default', 'photosFromStreetView')) {
            throw new \FTcms\Security\Acl\AuthorizationException('You are not authorized to import photos from street view.');
?>

ale v šabloně jsem to zapoměl taky oifovat, takže tam chybělo tohle:

<?php
{if $user->isAllowed('Facilities:Admin:Default', 'photosFromStreetView')}
    {control photosFromStreetViewDialog}
{/if}
?>

Editoval Ascaria (8. 11. 2013 11:13)

Filip Procházka
Moderator | 4668
+
0
-

Nechceš místo cachování do souborů použít například redis? To neustálé ukládání na disk tomu určitě nepomáhá.

Milo
Nette Core | 1283
+
0
-

Ve FileJournal je bug, zřejmě při hodně velkém btfj a je těžké ho zreprodukovat. Můžeš zkusit verzi, kterou tam Jakub Onderka zmiňuje.

Ascaria
Člen | 187
+
0
-

Tak jsem se přepočítal, teď jsem to nechal spočítat a má to 440 088 souborů a celkem 250MB ta cache včetně btfj.dat. Na jinou cache to dát nemůžu, protože nemám bohužel čas zkoumat jak ten redis rozjet. Takže budu muset tu cache nějak zlikvidovat.

Milo
Nette Core | 1283
+
0
-

Nebo můžeš zkusit přepnout na SQLiteStorage.

EDIT: Ale asi bych měl dodat, že je asi tak 15× pomalejší.

Editoval Milo (13. 11. 2013 13:54)