{"id":1834,"date":"2012-09-27T22:13:03","date_gmt":"2012-09-27T22:13:03","guid":{"rendered":"http:\/\/www.ollmetzer.com\/?p=1834"},"modified":"2013-05-20T10:10:13","modified_gmt":"2013-05-20T10:10:13","slug":"schnell-schneller-noch-schneller","status":"publish","type":"post","link":"https:\/\/www.ollmetzer.com\/?p=1834","title":{"rendered":"Schnell, schneller, noch schneller !!!"},"content":{"rendered":"<p>Ich war eben in Hamburg um Marco zu treffen. Marco ist als Webentwickler in San Francisco t\u00e4tig und gerade f\u00fcr kurze Zeit in Deutschland zu Besuch. Wir kennen uns seit zw\u00f6lf Jahren und sind beide seit geraumer Zeit f\u00fcr grosse E-Commerce Websites zust\u00e4ndig. Er im Bereich Publishing und Buchungssysteme und ich f\u00fcr Onlineshops. Den halben Nachmittag haben wir unter anderem f\u00fcr einen Erfahrungsaustausch genutzt. Obwohl &#8222;unsere&#8220; Systeme v\u00f6llig unterschiedlich sind, \u00e4hneln sich die Herausforderungen, mit denen wir konfrontiert werden. Zwei der wichtigsten Kriterien sind Belastbarkeit mit vielen Besuchern und Transaktionen sowie Geschwindigkeit.<\/p>\n<p>Zeit ist Geld. Nutzer warten nicht gerne. Ist die Website zu langsam, ziehen sie weiter. Google straft seit einiger Zeit ebenfalls Seiten im Pagerank ab, die langsam laden. Daraus folgern nochmals weniger Besucher. Wenige Zehntelsekunden k\u00f6nnen auf diese Weise durchaus einige tausend Euro ausmachen. Es lohnt sich also, Zeit und Geld in die Beschleunigung der Website zu investieren. Wir haben in unserer Firma in den letzten zehn Monaten sehr viele kleine und grosse Massnahmen zur Beschleunigung der Shops durchgef\u00fchrt, die in Summe wirklich sehr viel gebracht haben.<\/p>\n<p>Im Groben gibt es drei Bereiche, die f\u00fcr die Geschwindigkeit der Website verantwortlich sind:<\/p>\n<ol>\n<li><strong>Der Client<\/strong><br \/>\nLetztlich z\u00e4hlt, wie schnell der Browser des Nutzers reagiert. Es geht also um die Zeit zwischen Klick und fertiger Seite. Gegen langsame Rechner und Browser kann man als Websitebetreiber nichts machen. Aber man kann die Seiten so ausliefern, dass der Browser m\u00f6glichst wenig M\u00fche mit dem Rendern hat. Stichworte sind: Weniger komplexe Seiten, Reduzierung der Requests, mehr parallele Downloads.<\/li>\n<li><strong>Das Netzwerk<\/strong><br \/>\nHiermit ist alles zwischen Rechenzentrum und Nutzer gemeint. Hier hat man als Betreiber jedoch wenig Einfluss. Bei der Auswahl des Rechenzentrums sollte man auf redundante Anbindung aller relevanten Backbones und ausreichend verf\u00fcgbarer Bandbreite achten. Wenn die Zielm\u00e4rkte global verteilt sind, sollte die Nutzung eines spezialisierten Content Delivery Networks in Erw\u00e4gung gezogen werden.<\/li>\n<li><strong>Die Systemarchitektur<\/strong><br \/>\nWie baut man ein komplexes Setup aus unterschiedlichen Servern und Netzwerkger\u00e4ten im Rechenzentrum um die Inhalte m\u00f6glichst schnell ausliefern zu k\u00f6nnen? Genau das war der Schwerpunkt unseres Erfahrungsaustauschs.<\/li>\n<\/ol>\n<p>Interessanterweise sahen wir beide einige der momentan angesagten Methoden zur Realisierung von E-Commerce Sytemen eher etwas kritisch. Wir sind zum Beispiel beide f\u00fcr m\u00f6glichst schlanke Systeme zu haben, weil diese sowohl Ressourcen sparen, als auch Geschwindigkeit bringen.<\/p>\n<p><strong>Problembereich Frameworks<\/strong><\/p>\n<p>Komplexe Frameworks f\u00fcr eCommerce Systeme, auf die potentiell unbegrenzt viele Nutzer zugreifen k\u00f6nnen, sind unter den Aspekten Geschwindigkeit und Ressourcen eher schwierig. Zumal die Erfahrung zeigt, dass die damit beabsichtigte Beschleunigung von Entwicklungszyklen in der Realit\u00e4t oftmals nicht eintritt. Teilweise wird die Entwicklung sogar langsamer und fehleranf\u00e4lliger.<\/p>\n<p><strong>Cache as cache can<\/strong><\/p>\n<p>Auch der gerade sehr angesagte Einsatz von Full-Page Caches hat nicht nur Vorteile. Bei Publikationen (Onlinemagazine o.\u00e4.) sind sie voll in ihrem Element, k\u00f6nnen enorme Geschwindigkeitsvorteile bringen und die Content Management System entlasten. Ihre Geschwindigkeit kommt daher, dass sie fertige Seiten vorhalten und ohne grosse Verz\u00f6gerung an jeden Nutzer ausliefern k\u00f6nnen.<\/p>\n<p>Im eCommerce Umfeld macht aber genau die daraus resultierende geringe Flexibilit\u00e4t Probleme, wie ich am Beispiel einer Kategorieseite eines Onlineshops erl\u00e4utern m\u00f6chte.<\/p>\n<p><strong>Problemfeld Caching \u2013 ein einfaches Beispiel<\/strong><\/p>\n<p>Eine Kategorieseite besteht aus vielen Elementen, die erst aus der Datenbank zusammengesucht und dann zusammengebaut werden m\u00fcssen. Die Daten der Produkte, die in der Kategorie sind und der aktuellen Seitenzahl entsprechen, weitere Daten zur Kategorie selber (Titel, Beschreibungen, Links auf Headergrafiken usw.) und weitere Elemente, wie Kategoriebaum, Breadcrumbnavigation usw.<\/p>\n<p>Um solch eine Seite aufzubauen k\u00f6nnen durchaus hunderte einzelne Datenbankabfragen n\u00f6tig sein. Klar, das sowas dauert. Die Seite nur einmal zusammenzubauen und dann immer wieder fertig auszuliefern ist doch toll, oder?<\/p>\n<p>Darauf kann ich nur mit einem beherzten \u201e<em>jein<\/em>\u201c antworten. Die Seiten werden aus dem Cache teilweise 5-10 mal schneller ausgeliefert und belasten die Applicationserver nicht mehr. So weit so toll.<\/p>\n<p>Das gilt allerdings nur, solange die Standardseiten angezeigt werden. Sobald der Nutzer die Anzahl der anzuzeigenden Artikel pro Seite oder die Sortierung (nach Preis, Aktualit\u00e4t, Beliebtheit oder sonstwas, auf- oder absteigend) \u00e4ndert oder sogar Filter setzt, greift das tolle Caching nicht mehr, weil man derart viele m\u00f6gliche Seiten nicht mehr sinnvoll vorhalten kann.<\/p>\n<p>Ein weiteres Problem ist die Invalidierung der gecachten Seiten. In einem hochdynamischen System m\u00fcssen die erzeugten Seiten genauso schnell gel\u00f6scht und neu erzeugt werden, wie sich die zugrundeliegenden Daten \u00e4ndern. Ansonsten bekommt der Nutzer unentwegt veraltete und inkonsistente Daten angezeigt, wie z.B. Artikel, die gerade ausverkauft wurden.<\/p>\n<p>Wenn z.B. ein Artikel, der auf der ersten von 50 Kategorieseiten steht, gerade ausverkauft wurde, muss nicht nur seine Detailseite aus dem Cache entfernt werden, sondern ausserdem 50 Kategorieseiten neu erzeugt werden; die erste, weil er dort nicht mehr enthalten sein darf, und die 49 folgenden, weil sich die Position aller nachfolgenden Artikel ge\u00e4ndert hat.<\/p>\n<p>Dieses noch recht einfache Beispiel zeigt bereits viele potentielle Fehlerquellen. Hinzu kommt, dass sich personalisierte Seiten, die individuell f\u00fcr den Nutzer zusammengebaut werden, prinzipiell \u00fcberhaupt nicht cachen lassen. Von Problemf\u00e4llen wie mitgef\u00fchrten Sessions (Warenk\u00f6rben, personalisierten Einstellungen, Logins, Kampagnentracking) und so weiter ganz zu schweigen. Alles l\u00f6sbar, aber bei weitem nicht trivial und zum Teil hebelt man damit den Geschwindigkeitsvorteil des Full Page Caches wieder aus.<\/p>\n<p><strong>Less is more<\/strong><\/p>\n<p>Bleibt die Frage offen &#8222;&#8230;und wie bekommen wir das Ding nun schnell?&#8220;<br \/>\nPlatt gesagt durch Weglassen und Datenoptimierung.<\/p>\n<ul>\n<li>Full Page Caches sind toll f\u00fcr Publikationen, aber problematisch bei Transaktionssystemen. Nehmen wir diesen Komplexit\u00e4tslayer lieber aus dem System raus.<\/li>\n<li>Optimieren wir stattdessen den Applicationserver. Die verwendeten Frameworks m\u00fcssen schlank und schnell sein. Wenn f\u00fcr die Initialisierung der Anwendung mit Konfiguration und Aufbau der Datenbankverbindung schon 200ms draufgehen, brauchen wir gar nicht erst weitermachen.<\/li>\n<li>Pro anzuzeigender Seite d\u00fcrfen nur wenige und einfache Datenbankabfragen n\u00f6tig sein. Es kann sinnvoll sein, hochgradig <a title=\"Wikipedia: Datenbank Normalisierung\" href=\"http:\/\/de.wikipedia.org\/wiki\/Normalisierung_%28Datenbank%29\" target=\"_blank\">normalisierte<\/a> Datenstrukturen f\u00fcr die Anzeige zu Flattables zusammenzufassen.<\/li>\n<\/ul>\n<p>Der Erfolg eines solchen Vorgehens ist sp\u00fcrbar. Marco meinte zu einem Kunden, der den Einsatz eines Full-Page-Chaches anregte, sinngem\u00e4ss:<\/p>\n<blockquote><p>\u201eDie Seite in 200 Millisekunden fertig. Was willst Du da noch beschleunigen?\u201c<\/p><\/blockquote>\n<p>Nebenbei sei bemerkt, dass dieses System nicht nur pfeilschnell ist, sondern zudem mit sehr wenig Hardware betrieben wird.<\/p>\n<p>Und? Wie ist Euer Shopsystem so? ;-)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ich war eben in Hamburg um Marco zu treffen. Marco ist als Webentwickler in San Francisco t\u00e4tig und gerade f\u00fcr kurze Zeit in Deutschland zu Besuch. Wir kennen uns seit zw\u00f6lf Jahren und sind beide seit geraumer Zeit f\u00fcr grosse E-Commerce Websites zust\u00e4ndig. Er im Bereich Publishing und Buchungssysteme und ich f\u00fcr Onlineshops. Den halben [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,16,11],"tags":[],"class_list":["post-1834","post","type-post","status-publish","format-standard","hentry","category-development","category-ecommerce","category-onlinedienste"],"_links":{"self":[{"href":"https:\/\/www.ollmetzer.com\/index.php?rest_route=\/wp\/v2\/posts\/1834","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ollmetzer.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ollmetzer.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ollmetzer.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ollmetzer.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1834"}],"version-history":[{"count":1,"href":"https:\/\/www.ollmetzer.com\/index.php?rest_route=\/wp\/v2\/posts\/1834\/revisions"}],"predecessor-version":[{"id":1835,"href":"https:\/\/www.ollmetzer.com\/index.php?rest_route=\/wp\/v2\/posts\/1834\/revisions\/1835"}],"wp:attachment":[{"href":"https:\/\/www.ollmetzer.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1834"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ollmetzer.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1834"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ollmetzer.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1834"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}