Kategorie:
Services
Autor: Hellmann eCommerce
Fast Magento

Steigerung der Performance eines Magento-Shops Teil 1

Einundzwanzig. Ein Kolibri macht 90 Flügelschläge. Einundzwanzig. Ein Verkehrsflugzeug auf Reisehöhe legte eine Strecke von 244 Metern zurück. Einundzwanzig. Rund 7% der User eines Onlineshops geben entnervt auf, weil die aufgerufene Seite noch nicht dargestellt wurde. Zweiundzwanzig, dreiundzwanzig, vierundzwanzig. Und schon sind es 25% oder mehr, je nachdem welcher Statistik man Glauben schenkt…

Google wird schon seit Längerem nachgesagt, auch die Ladezeit einer Seite in seinen geheimen Rankingfaktoren zu berücksichtigen. Auch deshalb sollten Onlinehändler die Reaktionszeit ihres Shops im Auge behalten und so gut es geht optimieren. Wir haben uns im ersten Part dieses zweiteiligen Artikels mit der Serverseite befasst und eine Magento-Instanz auf zwei Beispielkonfigurationen geklont. Diese haben wir dann schrittweise optimiert und gegeneinander antreten lassen.

 

Was haben wir getestet?

Die Möglichkeiten der Optimierung sind vielfältig und sicher hat hier jeder Shopbetreiber sein eigenes Patentrezept bzw. Lieblingssetup, auf das er gerne zurückgreift. Für diese Testreihe konzentrierten wir uns daher auf die Auswirkung verschiedener Cachingstufen und der Geschwindigkeitssteigerung, die durch den Einsatz der alternativen PHP-Engine HHVM erzielt werden kann.

Unser Testsetup:

   Setup "PHP5"  Setup "HHVM"
 CPU DualCore@1.8 GHz
 RAM 18 GB
 OS CentOS 6.6
 Webserver Apache 2.2
 DB MySQL 5.5.42
 PHP  PHP 5.4.37  HHVM 3.5.0 via FastCGI

 

Wie haben wir getestet?

Unsere Tests führten wir allesamt auf der Maschine (localhost) selbst durch, um das Internet als potenziell verfälschende Komponente auszuschließen. Die Testtools fütterten wir mit einer URL-Liste typischer Shopbereiche (Startseite, Kategoriehauptseite, Produktliste, Produktdetailseite und Account-Login) und riefen diese abwechselnd in beiden Setups auf. 

Als Indikatoren zur Bewertung der Leistungsfähigkeit dienten uns dabei die folgenden Kennzahlen:

1. Seitenabrufe pro Minute (hits)

siege –b –c1 –t1M <url> 

(Benchmarkmodus mit einem User für eine Minute;
Benchmark– und Lasttool, http://www.joedog.org/siege-home)

2. Reaktionszeit des Servers (TTFB, time to first byte)

curl -o /dev/null -w "%{time_starttransfer} secs\n" <url>

(Kommandozeilen-Programm zum Herunterladen von Dateien über eine URL)

Erstes Ziel bei der Analyse und Optimierung der Shop-Performance sollte daher ein möglichst geringer TTFB-Wert (< 150ms) sein, stellt dieser doch die initiale Wartezeit nach Aufruf einer URL dar, bevor mit dem Herunterladen und Auswerten des HTML-Inhalts begonnen werden kann. Sind netzabhängige Faktoren (DNS, eigene Anbindung und geografische Entfernung zum Server) auszuschließen, kann ein hoher Wert  ein Anzeichen für Performanceprobleme auf dem Server selbst sein. Genau hier wollen wir ansetzen.

TTFB-Analyse

Abbildung 1: TTFB-Analyse mit der Chrome Entwicklertoolbar

 

HipHop Virtual Machine

Im Gegensatz zu anderen Programmiersprachen wie C++ oder Java wird der PHP-Quellcode (wenn keinerlei andere Optimierungsmaßnahmen greifen) bei jedem Seitenaufruf ausgewertet (sprich: interpretiert) und gelangt dann erst zur Ausführung. Die von Facebook entwickelte HipHop Virtual Machine oder kurz HHVM geht hier einen anderen Weg. Basierend auf einem just-in-time (JIT) Kompiler, wird der PHP-Quellcode in eine Zwischenstufe, den sog. HipHop bytecode übersetzt, der dann wiederum dynamisch in sehr schnell ausführbaren Maschinencode übersetzt wird. Diese Kompilierungsschritte müssen bestenfalls nur einmalig durchlaufen werden, was bei der wiederholten Ausführung viel Rechenzeit spart und einen spürbaren Performancesprung bringt.

Caches deaktiviert

Abbildung 2: Reaktionszeiten mit deaktiviertem Magento-Cache (weniger ist besser)

Der erste Testlauf mit deaktiviertem Magento-Cache soll daher zeigen, wie sehr sich der Wechsel auf die HHVM auswirkt, wenn beim Aufruf quasi der gesamte Seiteninhalt frisch erzeugt werden muss. Im schlimmsten hier gezeigten Fall muss der User also mehr als eine Sekunde warten, bevor überhaupt mit dem Download (und Aufbau) der Seite, der darzustellenden Bildern und Skripte etc. begonnen werden kann. Doch glücklicherweise ist dies nicht der Normalzustand.

 

Caching

Ein schönes Sprichwort besagt: „Was man nicht im Kopf hat, muss man in den Beinen haben.“ Auf unseren Fall angewendet, könnte es daher lauten: „Wenn Du etwas mehrmals brauchst, dann leg es Dir passend zurecht, anstatt es jedes Mal zurück zu legen und dann erneut holen zu müssen.“
Ein Cache ist daher nichts anderes als ein Ablageort für das Ergebnis bereits geleisteter, aufwendiger Rechenarbeit, auf den schnell zugegriffen werden kann.
Doch Caches sind kein Allheilmittel und sollten stets als letzter Schritt in einem Optimierungsprozess gesehen werden. Vorangegangen sein muss auf jeden Fall die Beseitigung von Performancebremsen wie z.B. generelle Fehlkonfiguration des Servers, ein langsames Datenbanksystem, zu wenig Arbeitsspeicher, langsame CPUs und Festplatten.
Magento bringt von Haus aus einen bunten Strauß an Caching-Möglichkeiten für die Konfiguration, Sprachdateien, HTML-Blockinhalte und einiges mehr mit. Auf beiden Systemen aktiviert, zeigt sich daher gleich ein ganz anderes Bild.

Nur Magentocache

Abbildung 3: Reaktionszeiten mit zugeschaltetem Magento-Cache (weniger ist besser)

Mit diesen Werten könnte man unter Umständen schon leben. Allerdings würde die noch recht große Verzögerung beim Laden der besonders wichtigen Produktlisten- und Produktdetailseiten die Userzufriedenheit sehr trüben und zu hohen Abbruchraten führen. Wir müssen also noch eine Schippe drauflegen.

 

Vorhang auf für Varnish

Der Webbeschleuniger Varnish wird von vielen namhaften Seiten eingesetzt, darunter das bereits genannte Facebook, aber auch Twitter, die New York Times und Vimeo. Varnish wird klassischerweise als sog. Reverse Proxy vor den Webserver geschaltet und empfängt die ankommenden Anfragen aus dem Internet. Ist ihm die angefragte Seite bekannt (es liegt ihm also bereits eine aktuelle Version des HTML-Inhalts dieser Seite vor) dann wird diese direkt ausgeliefert. Andernfalls erfolgt die Rückfrage an den eigentlichen Webserver, der bei diesem Szenario keinerlei direkte Verbindung zum Internet benötigt. Die Antwortzeiten wären also mit denen aus dem zuletzt gezeigten Testlauf vergleichbar. Dies gelingt gut bei komplett statischen Seiten, die also für alle User und jederzeit gleich aussehen. Oftmals ist es aber so, dass z.B. das Hinzufügen eines Artikels zum Warenkorb die angezeigte Artikelanzahl und Gesamtsumme verändert und auch so beim Refresh der Seite dargestellt werden soll. Also haben wir im Normalfall die Wahl, diese Seiten weiterhin ungecacht auszuliefern (was wahrscheinlich für 90% der Shopseiten zutrifft) oder ein Shop-Layout mit sehr wenigen dynamischen Elementen zu entwerfen. Wobei Letzteres wohl eher an Steinzeit-Shops erinnern dürfte. Glücklicherweise bietet Varnish die Möglichkeit, vom Caching ausgenommene Elemente einer Seite, wie etwa den Warenkorb, einzeln nachzuladen und den Rest der Seite weiterhin gecacht auszuliefern. Das Zauberwort lautet ESI (Edge Side Includes) und ist eine XML-konforme Auszeichnungssprache, mit deren Hilfe eben diese dynamischen Blöcke definiert und so Varnish bekannt gemacht werden können.

Beispiel:

<esi:include src="http://shop.com/esi/block/id/quickbasket" />

Bemerkt Varnish bei der Auslieferung einer Seite einen solchen ESI-Block, fragt es die darin eingebettete URL beim Webserver an und fügt dessen Antwort in das Gesamtkonstrukt ein. Im Idealfall ist dieser zusätzliche Request wesentlich schneller als die Neugenerierung der gesamten Seite und verhilft so zu einem deutlich spürbaren Performanceschub, ohne dabei auf den dynamischen Content verzichten zu müssen. Übertreiben sollte man es hierbei aber nicht. Zu viele ESI-Blöcke und damit verbundene Requests an den Webserver machen diesen Vorteil schnell wieder zunichte. Alternativ kann das Einfügen von dynamischen Blockinhalten auch durch den Browser über nachgelagerte Ajax-Requests erfolgen. Hierbei aktualisieren sich die so angeforderten Inhalte selbständig nach dem Aufbau der Seite, was nur selten als störend empfunden wird.
Das kostenlose Magento-Modul Turpentine bietet neben einer optimierten Varnish-Konfiguration auch die Funktionalität, typische dynamische Inhaltsblöcke automatisiert per ESI einzubinden.

Varnish aktiviert

Abbildung 4: Varnish beschleunigt die Auslieferung der Seiten immens (weniger ist besser)

Das Ergebnis spricht für sich. Trotz dynamischer Inhalte auf der Seite und der damit verbundenen Rückfragen an den Webserver sind die Antwortzeiten verschwindend gering. Es muss jedoch bedacht werden, dass wir hier direkt auf dem Server gemessen haben. Über das Internet würden wir TTFB-Werte von rund 50ms beobachten. Die relativ hohen Werte bei den Account-Seiten rühren daher, dass diese Inhalte gemeinhin nicht gecacht werden (können). Unter Umständen ist daher die Antwortzeit durch Varnish hindurch sogar geringfügig größer als direkt an den Webserver.

 

Fazit und Ausblick

Bei diesen Ergebnissen zeigt sich deutlich, wie sehr sich der Einsatz kluger Cachingmechanismen und der Einsatz der HHVM bezahlt machen. Dabei sollte beachtet werden, dass das Setup gerade bei einer hohen Anzahl gleichzeitiger Zugriffe anderen Anforderungen ausgesetzt sein wird und vielleicht sogar der Wechsel zu Nginx als Webserver sowie die Einbindung eines Caching-Backends wie Redis sinnvoll sein kann. Auf jeden Fall sollte ein Betreiber die maximalen Kapazitäten seines Shops kennen, indem er diese durch entsprechende Lasttests ermittelt und frühzeitig auf steigende Zugriffszahlen reagieren. Denn ein User, der aufgrund mangelhafter Performance den Kauf abgebrochen hat, kommt unter Umständen nicht wieder.

Zusammenfassung

Abbildung 5: Durchschnittswerte ohne Account-Seiten (TTFB: weniger ist besser, Transactions: mehr ist besser)

Im zweiten Teil dieser Artikelreihe werden wir uns mit der Ladezeiten-Optimierung der Seiteninhalte selbst befassen. Hierbei konzentrieren wir uns insbesondere darauf, die „gefühlte“ Geschwindigkeit bei der Nutzung des Shops zu erhöhen, was gerade bei mobilen Endgeräten eine große Rolle spielen kann.