Anzeige
Anzeige
Software & Entwicklung

Lösungen für eine bessere Performance in TYPO3 Version 4: TYPO3 ausreizen

Die dmc digital media center GmbH betreibt E-Commerce-Shops auf Basis von TYPO3 mit mehreren Millionen Seitenabrufen und über 100 Gigabyte Traffic pro Tag. Für einen reibungslosen Betrieb mit vertretbarem Bedarf an Hardware wurden zentrale Komponenten von TYPO3 erweitert oder ersetzt. In diesem Artikel stellen wir einige dieser Lösungen vor und geben Hinweise auf weiteres Potenzial zur Steigerung der TYPO3-Performance.

11 Min.
Artikel merken
Anzeige
Anzeige

Für Kunden im E-Commerce-Segment wurde eine Shop-Plattform auf Basis von TYPO3 entwickelt, welche die Stärken von TYPO3 als Content Management System nutzt, um typische Komponenten eines Onlineshops erweitert und diesen an diverse Backend-Systeme (ERP-Systeme, externe Dienstleister) anbindet. TYPO3 ist von Hause aus nur dann schnell, wenn eine Seite vollständig zwischenspeicherbar ist. Dies ist aber im E-Commerce-Umfeld mit dynamischen Warenkorbanzeigen und anderen benutzerabhängigen Elementen nur schwer bis gar nicht möglich.

Schnellere Webseiten bringen mehr Umsatz

Anzeige
Anzeige

Dieser Artikel stellt einige der Ad-hoc-Maßnahmen vor, die auch bei nur teilweise im Cache zwischengespeicherten Seiten noch einen hohen Durchsatz und damit möglichst kurze Wartezeiten bewirken. Zum einen erhöht eine schnelle Auslieferung der Webseiten die Kundenzufriedenheit und damit den potenziellen Umsatz des Shops. Zum anderen sind die Webserver schnell wieder „frei“ und können eine weitere Seitenanfrage für einen weiteren Kunden abarbeiten. Wenn mehrere hundert Benutzer gleichzeitig im System surfen und pro Tag sechs- bis siebenstellige Umsätze generiert werden, zählt nun mal jede Millisekunde.

Skalierbare Hardware-Landschaft

Um die hohe Anzahl an Seitenabrufen verarbeiten zu können, muss die Auslieferung der Seiten auf mehrere Webserver verteilt werden. Bewährt hat sich dabei die Verwendung eines Loadbalancers, der alle Anfragen von außen entgegennimmt und an ein Cluster von Webservern weiterleitet. Der Loadbalancer übernimmt zusätzlich die SSL-Verschlüsselung von sicherheitssensitiven Inhalten, etwa im Bestellprozess. Da der Loadbalancer dies durch ein Hardware-Modul erledigt, ist die Verschlüsselung deutlich schneller und entlastet die Webserver.

Anzeige
Anzeige

Jeder Webserver ist eine eigenständige Maschine (häufig IBM Blades) mit mindestens zwei CPU-Kernen und zwei Gigabyte RAM. Über ein Gigabit-Netzwerk sind alle Webserver miteinander und mit dem Loadbalancer verbunden.

Anzeige
Anzeige

Die TYPO3-Installation und sämtliche dazugehörigen Dateien liegen auf einem eigenen Server, der diese Dateien über ein Network Filesystem (NFS) global verfügbar macht. Sämtliche Webserver arbeiten also mit identischen Dateien. Die Änderung einer Datei auf einem der Webserver ist sofort auch allen anderen Webservern bekannt.

Treten etwa durch Marketingmaßnahmen Lastspitzen auf, die mit den bestehenden Webservern nicht mehr zufriedenstellend bewältigt werden können, ermöglicht die beschriebene Architektur, schnell und relativ kostengünstig weitere Webserver in den Cluster mitaufzunehmen und so den Durchsatz des Gesamtsystems zu erhöhen. Die potenziellen Umsatzverluste eines Systems dieser Größenordnung überschreiten schnell den Preis selbst mehrerer Webserver.

Anzeige
Anzeige

Die Datenbankinhalte liegen auf einem zentralen Server. Die Hardware entspricht in etwa der eines normalen Webservers, besitzt aber je nach Anforderung bis zu vier CPU-Kerne, acht GB RAM sowie größere und schnellere Festplatten im RAID-Verbund. Sämtliche für den Betrieb notwendigen Systeme (Loadbalancer, NFS-Server etc.) sind doppelt vorhanden. Sollte ein Loadbalancer wegen eines Hardwaredefekts ausfallen, übernimmt der zweite sofort die Anfragen und das Gesamtsystem bleibt online. Ähnlich verhält es sich bei den anderen Komponenten.

Gesamtperformance ist ein komplexes Uhrwerk

Um ein skalierbares Gesamtsystem zu erhalten, müssen sämtliche Komponenten reibungslos zusammenspielen und optimal konfiguriert sein. Die wichtigsten Komponenten sind hierbei verteilte Dateisysteme wie zum Beispiel NFS, die Datenbank (my.cnf), der Webserver (httpd.conf), aber auch Konfigurationen der Software wie TYPO3, die php.ini sowie eine saubere und effiziente Programmierung von TYPO3 selbst, der Extensions und anderer Komponenten.

Da viele der einzelnen Komponenten eng miteinander verzahnt sind, liegt es in der Natur der Sache, dass die Ursache für einen Flaschenhals nicht immer offensichtlich ist. Als Beispiel sei ein Performance-Engpass im zentralen Filesystem genannt. Jede „require()“-Funktion braucht dadurch wenige Millisekunden länger, was sich schnell aufsummiert. Als Symptom zeigt sich eine erhöhte CPU-Auslastung auf den Webservern, die mit der eigentlichen Ursache jedoch nichts zu tun haben.

Anzeige
Anzeige

Skalierungsproblem Datenbank

Wie oben beschrieben, ist es sehr einfach möglich, weitere Webserver in das System aufzunehmen. Bei der MySQL-Datenbank ist das nicht so ohne Weiteres möglich, da alle Webserver auf den gleichen Datenbank-Server zugreifen. Ab einer gewissen Menge von Anfragen skaliert MySQL auf einer Standard-Hardware nicht mehr mit. Jetzt bringen auch noch mehr und noch schnellere CPUs und mehr RAM nichts mehr. TYPO3 sollte daher von vornherein nicht mit persistenten Datenbankverbindungen arbeiten, zu erreichen durch „$TYPO3_CONF_VARS[‚SYS‘][’no_pconnect‘] = 1;“.

Dadurch baut PHP zwar ständig neue Verbindungen auf, diese verschwinden jedoch nach Abarbeitung des Skripts wieder aus dem Connection-Pool der Datenbank. MySQL muss daher weniger Connections verwalten als mit persistenten Verbindungen. Die Webserver können die auf ihrer Seite entstehenden zusätzlichen Befehle gut bewältigen.

Mittlerweile gibt es durch Replikationsmechanismen, so genannte „Read-Only Slave“- oder „Master-Master“-Konfigurationen, und durch die MySQL-Cluster-Engine (NDB) mehrere Lösungen, die das Verfügbarkeits- und Skalierungsproblem auf Datenbankseite zu lösen versuchen. In der Praxis zeigt sich jedoch sehr schnell, dass beide Lösungen mit Nachteilen behaftet sind, die einen Einsatz in einem Websystem überdenkenswert erscheinen lassen.

Anzeige
Anzeige

Die beste Lösung für ein TYPO3-System ist daher, die Anzahl der Anfragen an die Datenbank zu verringern und damit das Problem gar nicht erst aufkommen zu lassen. Wann immer durch Anpassung von Extensions eine Seite vollständig zwischenspeicherbar gemacht werden kann, sollte dies die erste Maßnahme sein.

ext:dmc_highPerformance

In der Extension „dmc_highPerformance“ [1] hat die dmc digital media center GmbH viele der an TYPO3 vorgenommenen Performance-Verbesserungen gebündelt. Die Extension ist im Extension Repository verfügbar und benötigt zusätzlich das Pear-Paket „PEAR::Cache“ [2] auf dem Server. Aktuell unterstützt die Extension die TYPO3-Versionen 4.0.5 bis 4.0.7 und 4.1.0 bis 4.1.2.

Die Extension „dmc_highPerformance“ beschleunigt die Performance von TYPO3 in verschiedenen Bereichen, die im Folgenden beschrieben werden. Vor der Installation der Extension sollte unbedingt die enthaltene Dokumentation gelesen werden, damit keine unerwünschten Nebeneffekte auftauchen.

Anzeige
Anzeige

Unnötiger Datenbank-Traffic

Auch bei teilweise oder vollständig im Cache zwischengespeicherten Seiten ist TYPO3 gezwungen, relativ viele Anfragen an die Datenbank zu stellen. Am häufigsten angefragt werden Daten aus den Tabellen „sys_template“ und „pages“. Nun sind aber gerade die Daten in diesen beiden Tabellen eher statisch, dennoch muss TYPO3 beispielsweise bei jedem Seitenabruf prüfen, ob die in einem Menü angezeigten Seiten unter den gerade gegebenen Umständen sichtbar sind oder nicht. Die Datenbank wird auf einem hoch frequentierten System also mit den immer gleichen Anfragen bombardiert.

So notwendig die Anfragen an die Tabellen „pages“ und „sys_template“ also auch sind, es spricht auf den meisten Systemen nichts dagegen, die Summe aller TypoScript-Templates oder die Erreichbarkeiten der TYPO3-Seiten für kurze Zeit zwischenzuspeichern – also zu cachen – und so die Last von der Datenbank zu nehmen. Selbst 60 Sekunden Cache-Gültigkeit sparen der Datenbank viele hundert Anfragen pro Minute und machen das Gesamtsystem spürbar schneller. Stellt sich nur die Frage: Wohin mit den Caches?

Zusätzliches Caching durch PEAR::Cache

Das Modul „PEAR::Cache“ ist in der Lage, beliebig strukturierte Daten zwischenzuspeichern. Aus Performance-Gründen bietet sich das Caching in Dateien an, die Datenbank soll schließlich entlastet werden. Dabei muss vermieden werden, Daten im Netzwerkdateisystem zwischenzuspeichern, da dieses langsamer ist als ein lokales Dateisystem. Zwar muss dann jeder Webserver seinen eigenen Cache verwalten, was die Anzahl der Datenbankanfragen zunächst wieder erhöht. Jedoch rechtfertigt der Gewinn an Geschwindigkeit diesen Nachteil.

Anzeige
Anzeige

Nun geht es also darum, den Kern von TYPO3 so zu erweitern, dass Daten an den richtigen Stellen über PEAR::Cache zwischengespeichert werden.

Caching von Datenbankanfragen

Die umfangreichste Erweiterung, die am TYPO3-Kern vorgenommen wurde, betrifft das eben beschriebene Caching von Datenbankergebnissen. Das PEAR::Cache-Modul wird verwendet, um MySQL-Ergebnisse als PHP-Arrays in Cache-Dateien zwischenzuspeichern, die im lokalen Filesystem liegen. Das Lesen und Aufbereiten einer PEAR::Cache-Datei ist ähnlich schnell wie eine Datenbankanfrage, sofern die Datenbank nicht überlastet ist. Durch das lokale Caching kann also die Last auf die Datenbank extrem verringert werden.

Aus diesem Grund besitzt die in „dmc_highPerformance“ enthaltene Klasse „highPerformance“ eine Gruppe von Methoden, die es erlaubt, SQL-Statements ohne große Eingriffe in den TYPO3-Kern zwischenzuspeichern. Zwar müssen mangels Hooks immer noch viele Klassen und Methoden über die XCLASS-Logik überschrieben werden. Die Änderungen sind jedoch klar ersichtlich und ein Vergleich der Original-Methode mit der überschriebenen geht bei einem Update auf eine aktuellere TYPO3-Version leicht von der Hand. Das Anlegen einer Instanz der PEAR::Cache-Klasse sowie die Generierung der Cache-IDs finden transparent innerhalb der Klasse „highPerformance“ statt.

Anzeige
Anzeige

Wird über das TYPO3-Backend der Frontend-Cache gelöscht, müssen auch die PEAR::Cache-Dateien von den Webservern entfernt werden. Dies wird durch einen Hook realisiert. Damit das reibungslos funktioniert, müssen allerdings alle internen Hostnamen der Webserver in einem Cluster in der Extension konfiguriert werden. Auch muss es möglich sein, zwischen den Webservern eines Clusters via HTTP zu kommunizieren.

MySQL-Query-Cache besser nutzen

MySQL speichert häufig abgesetzte Statements im Query-Cache mitsamt ihrem Ergebnis im Hauptspeicher zwischen – sofern der Query-Cache aktiviert ist [3]. Dabei ist sehr wichtig, dass wirklich nur identische Statements aus dem Cache wieder ausgelesen werden, eine kleine Veränderung beispielsweise an der WHERE-Klausel führt dazu, dass MySQL den Query-Cache ignoriert und das Statement erneut ausführt.

TYPO3 arbeitet in seinen Datenbanktabellen häufig mit Zeitstempeln (Timestamps), um zu ermitteln, wann eine Seite, ein Seitenelement oder ein TypoScript-Template online oder offline gehen soll. Ebenso werden Cache-Gültigkeit und andere Dinge über sekundengenaue Timestamps verwaltet.

An und für sich ist dagegen nichts einzuwenden, jedoch führt ein SQL-Statement à la „…WHERE pages.starttime<=$GLOBALS[‚SIM_EXEC_TIME‘] …“ dazu, dass der Query-Cache von MySQL im Sekundentakt ungültig wird. Hier sollte man sich die Frage stellen, ob zu Gunsten einer besseren Effizient des Query-Caches und damit einer insgesamt besseren Performance des Systems die Genauigkeit der Online- und Offline-Zustände wirklich bei einer Sekunde liegen muss. Eine Genauigkeit von zehn Minuten sollte ebenfalls ausreichen und erhöht zudem die Wirksamkeit des MySQL-Query-Caches.

Daher wurde die statische Methode „highPerformance::roundTime()“ in die Extension implementiert und relevante Stellen im TYPO3-Kern so umgeschrieben, dass „roundTime()“ zur Rundung von Timestamps verwendet wird. Die Methode verfügt über einen optionalen zweiten Parameter, über den der Rundungsfaktor von zehn Minuten in Einzelfällen angepasst werden kann.

REPLACE statt DELETE und INSERT

TYPO3 benutzt bei einigen Tabellen, insbesondere bei den hoch frequentierten Tabellen für die Caches und die Frontend-Sessions, eine Kombination aus einem DELETE- und einem anschließenden INSERT-Statement, um Inhalte zu aktualisieren. Im Falle des Frontend-Caches ist die Logik kurz gesagt diese: Wird eine Cache-fähige, aber noch nicht zwischengespeicherte Seite aufgerufen, legt TYPO3 zunächst einen temporären Eintrag in der Cache-Tabelle an. Ab jetzt sehen Besucher der Webseite die Meldung „Page is being generated“. Unterdessen läuft die unter Umständen zeitaufwändige Generierung des HTML-Codes ab. Anschließend wird der temporäre Eintrag in der Datenbank über DELETE gelöscht und das soeben generierte HTML mittels INSERT in die Tabelle geschrieben. Von jetzt an ist die Seite zwischengespeichert und zukünftige Besucher sehen den Inhalt, den TYPO3 soeben in die Datenbank geschrieben hat.

Das Problem dabei: Zwischen dem DELETE- und dem INSERT-Statement vergeht ein klein wenig Zeit. Auf großen Systemen kann das zu einer so genannten „Race-Condition“ führen, bei der sich parallel laufende Prozesse gegenseitig behindern. Die Folge: Es besteht eine hohe Wahrscheinlichkeit, dass die Seite „Page is being generated“ nicht mehr verschwindet.

Glücklicherweise verfügt MySQL über ein REPLACE-Statement. Es verhält sich wie ein UPDATE-Statement, wenn ein durch die WHERE-Klausel definierter Datensatz bereits existiert. Ist das nicht der Fall, verhält sich REPLACE genau wie INSERT. Es wird also nur ein einzelnes Statement an die Datenbank geschickt, Race-Conditions sind dadurch ausgeschlossen.

Die Extension „dmc_highPerformance“ integriert eine Methode namens „t3lib_db::exec_REPLACEquery()“ in den Datenbank-Layer von TYPO3 und ersetzt an relevanten Stellen die bisherige DELETE/INSERT-Logik. Der Nachteil dieses Ansatzes: Für alle eingehenden Anfragen wird die Seite solange vollständig gerendert, bis dieser Vorgang abgeschlossen ist und der Cache-Inhalt in die Datenbank geschrieben wurde.

REPLACE ist nicht Teil des SQL-ANSI-Standards und steht daher für andere Datenbanktypen nicht unbedingt zur Verfügung. Eine Alternative zur Kombination DELETE/INSERT ist UPDATE/INSERT. Dabei wird zunächst versucht, einen Datensatz zu aktualisieren – egal ob dieser bereits existiert oder nicht. Schlägt das UPDATE fehl, weil kein Datensatz gefunden wurde, kann dieser über INSERT eingefügt werden. Nachteile dieser Methode gegenüber der Kombination DELETE/INSERT ist jedoch, dass das UPDATE-Statement in aller Regel einen Fehler produziert, der geloggt wird sowie die Tatsache, dass immer noch zwei statt einem Statement benötigt werden, was Zeit kostet.

Master-Slave-Replikation von MySQL optimieren

Teil der Lösung für ein hochverfügbares System ist eine Master-Slave-Replikation der Datenbank. Hierbei existieren zwei Server, auf denen eine MySQL-Datenbank läuft. Eine Maschine – der Master – ist TYPO3 bekannt. Alle Anfragen, lesend wie schreibend, werden an den Master gestellt und von ihm beantwortet.

Die zweite Maschine – der Slave – wird nicht aktiv benutzt. Stattdessen dient er als „Backup“, falls der Master auf Grund von Defekten an der Hardware ausfallen sollte. Um das zu erreichen, wird auf dem Master das so genannte „Binlog“ aktiviert. Der MySQL-Master schreibt nun alle die Datenbank verändernden SQL-Statements in ein binäres Logfile. Der oder die Slaves wiederum lesen dieses Binlog aus und führen die Statements auf ihren lokalen Tabellen ebenfalls aus. Auf diese Weise wird der Zustand der Daten des Masters fast in Echtzeit auf die Slaves repliziert. Fällt der Master aus, sind die Daten noch vorhanden und der Slave kann so umkonfiguriert werden, dass er zum Master wird. Details zu diesem Verfahren liefert das MySQL-Handbuch [4].

Nun ist es nicht unbedingt sinnvoll, jedes Statement, das TYPO3 an die Datenbank absetzt, auf die Slaves zu replizieren, weil das Schreiben des Binlogs ebenfalls Last auf der MySQL-Maschine verursacht. Die Cache-Tabellen und eventuell auch die Frontend-Sessions müssen nicht unbedingt gesichert werden. Solange die Last es erlaubt, bringt die Replikation dieser Daten Vorteile, aber wirklich nötig ist sie bei vielen Systemen nicht.

Leider kann man in MySQL das Binlog nicht so konfigurieren, dass einzelne Tabellen aus der Replikation ausgenommen werden, lediglich einzelne Datenbanken lassen sich ausschließen. Allerdings ist es möglich, innerhalb einer Datenbank-Connection per SQL-Statement die Replikation kurzzeitig ein- und auszuschalten, wenn der MySQL-Benutzer über SUPER-Privilegien verfügt.

Die Lösung: Über die statische Methode „highPerformance::switchMySQLBinLog()“ wird geprüft, ob das MySQL-Binlog zurzeit aktiv ist und anschließend deaktiviert, sofern das gewünscht ist. Ein erneuter Aufruf der Methode schaltet das Binlog wieder ein. Die dafür relevanten Methoden des TYPO3-Kerns wurden so überschrieben, dass sie das Binlog deaktivieren, bevor sie ein schreibendes Statement, etwa auf die Cache-Tabellen, absetzen und es anschließend wieder aktivieren. Die Optimierung des Binlogs muss über die PHP-Konstante „MYSQL_BINLOG_SPEEDUP“
aktiviert werden.

Fazit

Im Auslieferungszustand tut sich TYPO3 mit hoher Performance relativ schwer, man merkt dem Code seine langjährige Entstehung deutlich an. Einige mitgelieferte Funktionen, die einen Performance-Gewinn versprechen, lassen sich bei im Cluster betriebenen Webservern zudem gar nicht oder nur über Anpassungen einsetzen, etwa das HTML-Caching in lokale Dateien über „$TYPO3_CONF_VARS[FE][pageCacheToExternalFiles]“. Insbesondere die hohe Abhängigkeit von der Datenbank stellt so etwas wie eine Sackgasse dar.

Dennoch lässt sich TYPO3 in Version 4 mit etwas Aufwand auch für sehr große dynamische Websysteme einsetzen. Die hier vorgestellte Extension „dmc_highPerformance“ kann diesen Aufwand verringern, da sie wichtige Maßnahmen zur Performance-Verbesserung bündelt. Die Entwicklung der von Grund auf neuen TYPO3-Version 5.0 ist bereits in vollem Gange. Man darf gespannt sein, welche Richtung TYPO3 5.0 in Sachen Performance einschlägt.

Mehr zu diesem Thema
Fast fertig!

Bitte klicke auf den Link in der Bestätigungsmail, um deine Anmeldung abzuschließen.

Du willst noch weitere Infos zum Newsletter? Jetzt mehr erfahren

Anzeige
Anzeige
Schreib den ersten Kommentar!
Bitte beachte unsere Community-Richtlinien

Wir freuen uns über kontroverse Diskussionen, die gerne auch mal hitzig geführt werden dürfen. Beleidigende, grob anstößige, rassistische und strafrechtlich relevante Äußerungen und Beiträge tolerieren wir nicht. Bitte achte darauf, dass du keine Texte veröffentlichst, für die du keine ausdrückliche Erlaubnis des Urhebers hast. Ebenfalls nicht erlaubt ist der Missbrauch der Webangebote unter t3n.de als Werbeplattform. Die Nennung von Produktnamen, Herstellern, Dienstleistern und Websites ist nur dann zulässig, wenn damit nicht vorrangig der Zweck der Werbung verfolgt wird. Wir behalten uns vor, Beiträge, die diese Regeln verletzen, zu löschen und Accounts zeitweilig oder auf Dauer zu sperren.

Trotz all dieser notwendigen Regeln: Diskutiere kontrovers, sage anderen deine Meinung, trage mit weiterführenden Informationen zum Wissensaustausch bei, aber bleibe dabei fair und respektiere die Meinung anderer. Wir wünschen Dir viel Spaß mit den Webangeboten von t3n und freuen uns auf spannende Beiträge.

Dein t3n-Team

Melde dich mit deinem t3n Account an oder fülle die unteren Felder aus.

Bitte schalte deinen Adblocker für t3n.de aus!
Hallo und herzlich willkommen bei t3n!

Bitte schalte deinen Adblocker für t3n.de aus, um diesen Artikel zu lesen.

Wir sind ein unabhängiger Publisher mit einem Team von mehr als 75 fantastischen Menschen, aber ohne riesigen Konzern im Rücken. Banner und ähnliche Werbemittel sind für unsere Finanzierung sehr wichtig.

Schon jetzt und im Namen der gesamten t3n-Crew: vielen Dank für deine Unterstützung! 🙌

Deine t3n-Crew

Anleitung zur Deaktivierung
Artikel merken

Bitte melde dich an, um diesen Artikel in deiner persönlichen Merkliste auf t3n zu speichern.

Jetzt registrieren und merken

Du hast schon einen t3n-Account? Hier anmelden

oder
Auf Mastodon teilen

Gib die URL deiner Mastodon-Instanz ein, um den Artikel zu teilen.

Anzeige
Anzeige