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

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
Moderator | 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
Moderator | 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)

RSS tématu Téma zavřeno