Oxid Enterprise Caching

Der Oxid eShop bietet in der Enterprise Version eine ausgefeilte und flexible Caching Strategie an. Es gibt die Möglichkeit, verschiedene Caching-„Backends“ zu nutzen bzw. auch eigene Backends zu implementieren. Gecached werden können theoretisch sämtliche Shop-Klassen, um z.B. konkret Startseite, Kategorieübersichten oder Detailseiten usw. zu cachen und damit als (weitgehend) „statisches“ HTML auszuliefern, um die Shop-Performance zu steigern.

Die gewünschten Klassen können im Shop-Admin unter „Stammdaten – Caching“ eingetragen werden. Standardmäßig ist im Shop als Caching-Backend der „OXID eShop Disk Storage Cache“ verfügbar, der die Cache-Daten als „.cache“-Dateien im „/tmp“-Verzeichns des Shops ablegt und eine Referenz darauf in der „oxcache“-Datenbanktabelle einträgt. Hat man auf dem Server die „Zend Plattform“ installiert, so steht auch ein Zend Cache-Backend zur Verfügung. Es ist aber auch problemlos möglich, eigene Backends einzusetzen, die lediglich ein bestimmtes Interface implementieren müssen und damit Methoden zu bieten, Daten im Cache zu speichern, wieder auszulesen und schliesslich auch wieder zu löschen. Exemplarisch sei hier ein „Memcached„-Backend genannt, das Shoptimax für einen Kunden umgesetzt hat, um das Caching effizienter zu machen und für verteilte Shop-Server (Loadbalancer/Cluster) mit verteilten tmp-Verzeichnissen zu optimieren – hier hat man sonst eine hohe sog. „Cache Miss“-Rate (und dadurch letztlich eine schlechtere Performance), da die „.cache“-Dateien zwar in der Datenbank noch referenziert werden, teilweise aber im Dateisystem nicht gefunden werden, da sie unter Umständen nicht auf demselben Cluster-Server im dortigen „tmp“-Verzeichnis des Shops liegen, auf dem auch der Shop-Kunde aktuell mit dem Browser „gelandet“ ist.

Nicht immer sollen jedoch komplette Shop-Seiten gecached werden, Informationen wie Warenkorbinhalt, Login-Name, Verfügbarkeitsanzeigen usw. sollen natürlich immer aktuell sein. Zu diesem Zweck „injiziert“ der Oxid EE Shop in die gecachten Seiten dynamische „Snippets“, dafür sorgt die Smarty-Funktion „oxid_include_dynamic„. Diese inkludiert Smarty Template-Schnippsel (normalerweise aus dem „out/basic/tpl/dyn“ Verzeichnis) in die gewünschte Seite bzw. das gewünschte Template. Hier ein Beispiel das die Warenkorbinhalte dynamisch einbindet:

[{oxid_include_dynamic file=“dyn/mini_basket.tpl“ type=“basket“ extended=true testid=“RightBasket“}]

Wichtig ist hierbei, dass an ein solches „dynamisches“ Template kein Objekt als Argument übergeben werden kann, wie dies bei normalen Templates der Fall ist, also z.B. ein “ … product=$product …“ o.ä ist hier nicht möglich. Stattdessen muss in einem solchen Fall z.B. ein String oder Integer-Wert übergeben werden wie etwa die Produkt-Id, im Beispiel also etwa “ … productid=$product->oxarticles__oxid-value …“. Hintergrund ist, dass die Parameter-Werte per base64_encode() und base64_decode() umgewandelt und übertragen werden. Um den übergebenen Parameter dann auszuwerten und z.B. das gewünschte Objekt zu erzeugen/laden und wiederum im Template zur Verfügung zu stellen, ist es nötig, die Funktion oxCache::_processDynContent() per Modul zu überschreiben und mit der gewünschten Logik zu erweitern. Um auf die übergebenen Parameter direkt im inkludierten, dynamischen Template zugreifen zu können, muss man zudem einen Unterstrich (Underscore) „_“ davor setzen, im Beispiel also [{$_productid}], da in der Methode oxCache::_processDynContent() alle Variablen mit diesem Prefix versehen und wieder in das Template geschrieben werden.
Will man aus irgendwelchen Gründen Template-Logik nur bei aktivem Caching einbinden, kann man die Variable $_render4cache abfragen, die in diesem Falle in allen Templates verfügbar ist:

[{if $_render4cache}]
    Sie sehen eine gecachte Version der aktuellen Seite!
[{/if}]

Fazit: Für größere Shops mit sehr vielen Kategorien und/oder Artikeln ist Caching im OXID eShop eigentlich unerlässlich, wir konnten in manchen Shops und mit bestimmten Shop-Klassen eine Performance-Steigerung um den Faktor 5 feststellen – nicht nur im Hinblick auf Google-Ranking von Vorteil, sondern generell für die Usability und Akzeptanz des Shops durch die Kunden.

4 Antworten
  1. Andreas Ziethen says:

    Sehr guter und aufschlussreicher Beitrag!
    Zu erwähnen wäre noch, dass ein vollständiges Content-Caching, wie es der OXID-Shop anbietet, in manchen Situation leider nur bedingt brauchbar ist:

    Wenn ein Shop an ein ERP-System angeschlossen ist und z. B. minütlich Bestandsupdates von dort erhält, die auch die Verfügbarkeitsanzeige im Shop steuern, so ist es quasi unmöglich, die Listenseiten zu cachen. Denn Änderungen der Verfügbarkeitsanzeige (Ampel) – oder Funktionen wie „wenn ausverkauft offline“ würden hier nicht funktionieren – bzw. würde bei großen Verkaufszahlen ständig der komplette Cache resettet, was dann auch wieder nicht hilfreich ist.

    Hier ist also dann noch ein bißchen mehr Logik erforderlich, um auch in solche Situationen ein effektives Caching zu bauen.

    Antworten
  2. shoptimax says:

    Hallo Andreas, vielen Dank! Ja, guter Punkt, das ist tatsächlich ein Problem. Wir haben auch einige EE-Kunden mit ERP-Anschluss, wo dann sobald Updates z.B. über die SOAP-Schnittstelle kamen, der Cache komplett gelöscht wurde, was natürlich sehr kontra-produktiv ist, wenn dies mehrmals pro Stunde geschieht.
    Lösungsansätze gibt es hier verschiedene, der sauberste ist vermutlich der, die Artikel-Verfügbarkeit komplett auszulagern in eine eigene Tabelle, was wir bei einem Kunden gemacht haben. Ein anderer Ansatz ist, die Cache-Funktionalität soweit anzupassen, dass der Cache nur unter bestimmten Voraussetzungen gelöscht wird und nicht bei jedem (SOAP-)Update. Generell sollte man die Funktion zum Löschen des Caches, die ja von zahlreichen Stellen im Shop aus getriggert wird, an die Shop-Bedürfnisse anpassen, um einfach selektiver den Cache löschen zu können… ein wichtiger Punkt ist dabei z.B. auch das Häkchen im Admin,
    den Cache nur beim Ausloggen aus dem Admin-Bereich zu löschen und nicht bei jedem Speichern usw.

    Antworten
  3. Michael Oehme says:

    Sehr interessanter Artikel!
    Für mich stellt sich auch Frage, wie man mit der Problematik umgeht, wenn der User Cookies ausschaltet und die SessionID als CGI-Parameter an alle Links angehängt wird.
    Dies betrift dann nicht nur einzelne Snippets, sondern fast alle Bereiche der Templates.

    Antworten
    • shoptimax says:

      Hi Michael, eigentlich gibt es in der Klasse oxCache die Funktionalität, alte „sid=…“ Formularfelder usw. mit der jeweils aktuellen Session-ID zu ersetzen – also auch die gecachten Seiten sollte dynamisch beim Einlesen mit einer gültigen SID in allen hidden Feldern, Links usw. versehen werden. Oder meinst Du was anderes?

      Antworten

Hinterlassen Sie einen Kommentar

Wollen Sie an der Diskussion teilnehmen?
Wir freuen uns über ihren Beitrag!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.