• Willkommen im Zend Framework Forum

    ZF1 Zend Framework 1 + ZF2 Zend Framework 2

    Das Zend Framework Forum ist seit 2006 die erste Anlaufstelle für Zend Framework Entwickler in Deutschland. Mit über 70.000 Beiträgen und einer steigenden Nutzerzahl bietet das Forum hilfreiche Themen und ZF-Tutorials für professionelle Entwickler, fortgeschrittene Programmierer sowie Zend Framework Einsteiger.
    Wenn dies Dein erster Besuch in der Zend Framework Community ist, lies bitte zuerst die Hilfe - FAQ durch. Du musst Dich registrieren, bevor Du Beiträge verfassen kannst. Klicke oben auf 'Registrieren', um die Registrierung zu starten. Du kannst auch jetzt schon Beiträge lesen. Hier im Forum findest Du die Zend Framework Hilfe, die Du suchst!

    Grüße an alle Zend Framework Entwickler. Das Team vom Zend Framework Forum!

    Drupal Agentur

Doctrine 2 und Caching (Hier: APC)

Powers

New member
Hi!

Ich habe eine Frage an die Doctrine 2-Nutzer unter euch, wie ihr das mit mit dem Cachen von Datensätzen umgeht (was prinzipiell dringend von den Machern empfohlen wird).

Ich habe mich nun gut zwei Tage mit allen möglichen Cache-Mechianismen beschäftigt und wäre auch mit dem implementieren der "Zend\Cache\StorageFactory" völlig zufrieden gewesen, wenn dort nicht der Ärger mit verschachtelten Objekten wäre. Ähnlich wie beim speichern von Objekten in Sessions, werden auch beim Zend-Cache die Unterobjekte von Objekten leider nur mit "__php_incomplete_class" gespeichert. Habe auch auf einer Webseite gelesen, dass Doctrine *toOne und *toMany-Relationen in einem solchen Fall nicht auflösen würde. Konnte das leider nicht lösen, weder durch Serialisierung noch anderen Kram. Ich hätte wohl eigens eine ObjectCopy-Funktion schreiben müssen. Wie das aber so ist, habe ich dann ohnehin mehrfach gelesen, dass diese Vorgehensweise nicht erwünscht ist und man einen der Zahlreichen Doctrine-Cache-Klassen nutzen sollte (siehe 24. Caching — Doctrine 2 ORM 2 documentation)

Ich habe mich für den APC-Cache entschieden, der so allgemein Einzug zu erhalten scheint (kam mir bei Typo3 einst unter die Augen).

Prinzipiell kann man alles was man möchte folgend speichern:
PHP:
$cacheDriver = new \Doctrine\Common\Cache\ApcCache();
$cacheDriver->save('cache_id', 'my_data');
Funktioniert auch genau so einfach wie geschrieben und kann neben "save" fortführend u.a. mit den Funktionen "fetch" und "delete" gehandhabt werden (Siehe \Doctrine\Common\Cache\CacheProvider.php).
Aber auch hier: Doctrine-Objekte werden leider ohne ihre Unterobjekte gespeichert -> selbiges Problem wie oben angesprochen.

Also geht es wohl noch eine Nummer schöner, indem man einfach alles in Sachen Doctrine mit in den Cache mit einbindet. Neben der normalen Doctrine-Konfiguration soll nicht mehr notwendig sein als folgende Erweiterung:
PHP:
'doctrine' => array(
        'driver' => array(
            __NAMESPACE__ . '_driver' => array(
                'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
                'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Doctrine')
            ),
            'orm_default' => array(
                'drivers' => array(
                    __NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver',
                ),
            ),
            // Neu für APC caching 
            'cache' => array(
                'class' => 'Doctrine\Common\Cache\ApcCache'
            ),
            'configuration' => array(
                'orm_default' => array(
                    'metadata_cache' => 'apc',
                    'query_cache'    => 'apc',
                    'result_cache'   => 'apc',
                    'generate_proxies' => false,
                )
            ),
        )
    ),
Mit der PHP-Funktion "apc_cache_info()" kann man nachvollziehen, dass bzw ob der Cache mit jedem Neuladen der Seite auch mitarbeitet. Laut dem dritten Beitrag von How to check if APC opcode cache is working fine in PHP? - Stack Overflow muss man beim neuladen nur darauf achten, dass die angezeigten "num_hits" steigen. Dies ist bei mir der Fall.

Es ist jetzt aber nicht so, als ob meine Webseite plötzlich flitzen würde. Meine Suchfunktion ist im Vergleich immernoch deutlich schneller durch die indexierten Dateien (was ja logisch ist, dafür ist es ja gemacht). Aber eine ähnliche Performance hatte ich mir durch das Cachen eigentlich auch erhofft.

Weiß denn in dem Zusammenhang auch jemand, ob es tatsächlich hilft, wenn man nun beim APC-Cache darüberhinaus bei den eigenen Datenbank-Abfragen mit "query->userResultCache()" arbeitet?
Funktioniert wie hier beschrieben: Using APC cache inside Symfony2 for caching Doctrine2 results
- wenn ich auch die versprochene Performance-Steigerung nicht konkret nachvollziehen kann.

Cache hin, Cache her - laut Firebug->Netzwerk benötigt eine meiner Seiten lokal zwischen 0.9 und im schlechtesten Fall etwa 1.5 Sekunden zum laden. Nur eine Seite mit nur einem Artikel aus der Datenbank (statt 7 pro Seite) läd zügiger mit weniger als 0.5 Sekunden.
Aber ich habe das Gefühl, dass Ausschläge nach unten (wenig Ladezeit) ggf auch Zufall sind, wenn ich gerade den Cache aktiviert habe. Denn auch ohne Cache kann es sein, dass die Ladezeit mal unter einer Sekunde liegt.

Gibt es "hard facts" denen man nachgehen kann, um sowas zu testen? Oder auch: Welche Strategien verfolgt ihr beim cachen, um sich wiederholende Datenbankabfragen bei Doctrine zu verhindern?

Edit: In Sachen Ladezeit hat sich nun einiges getan, nachdem ich einige API-Anfragen nun in Zend/Cache gepackt habe. Praktisch jede Seite läd nun innerhalb von 0.2 Sekunden. Über Antworten hier zum Thema APC (nach wie vor aktuell) würde ich mich freuen :)
 
Zuletzt bearbeitet:
Oben