Drupal-Performance-Odysee mit Happy-End
Mit dem Update unseres Intranet-Portals von D5 auf D6 und dem gleichzeitigen Umzug der Installation von einem virtuellen Webserver (Xen+Linux) auf einen physischen Server (auch Linux, identische Hardware) handelte ich mir einen totalen Einbruch der Performance der Seite ein. Ein “normaler” Seitenaufruf dauerte ~7 Sekunden, für die Startseite (mit Panels voller Views-Blöcke) dauerte das Laden ~13 Sekunden. Somit war das Intranet-Portal praktisch unbenutzbar.
Nachdem ich mich von dem schrecken erholt hatte, begann ich mit der Ursachenforschung.
Den Einstieg bekam ich mit Ingos Blog-Eintrag.
Von dort ging es weiter zu http://2bits.com/articles/drupal-performance-tuning-and-optimization-for-large-web-sites.html und dem sichten der extra-langen Liste nach anwendbaren Vorschlägen.
Mein erster Kandidat war die MySQL-Datenbank. Sie läuft auf dem selben Rechner wie der Web-Server also keine zu überprüfende Netzwerk-Kommunikation. Also nahm ich das tuning-primer.sh-Skript und optimierte den DB-Server, so lange mir die Vorschläge plausibel erschienen und endlich alle Tests auf Grün standen. Keine Verbesserung.
Auch zeigte das devel.module, dass nur ein Bruchteil der Ladezeit für die SQL-Queries benötigt wurde.
Als nächstes (wenige Tage später) nahm ich mir den Apache vor. Auf ihm laufen neben PHP-Skripten (drupal, phpmyadmin) auch diverse Python-Apps und ein Scalix mit Tomcat-Servlet-Connector. Ich entfernte alle Apache-Erweiterungen, die nicht unbedingt benötigt werden (z.B. _mod_userdir_ und _mod_info_). Dann noch .htaccess-Konfigurationen in die statische Server-Konfiguration übernommen und eaccelerator installiert. Keine Verbesserung.
Zwischendurch habe ich ein Benchmark eingeschoben, um von der “gefühlten” Trägheit des Servers zu vergleichbaren Werten zu kommen und vielleicht schon kleine Verbesserungen wahrnehmen zu können.
Das Ergebnis:
ab -n50 -c2 -dS http://portal.firma.de/node/111
...
Connection Times (ms)
min avg max
Connect: 49 105 302
Processing: 11182 12339 16441
Total: 11231 12444 16743
Frustrierend!
Ich hatte als nächstes den verdacht, dass der Apache (2.0.18) mit der Multifunktionalität zu kämpfen hat und nicht gleichzeitig ein guter PHP- und Servlet-Host sein kann. Außerdem wollte ich mal lighttpd und FastCGI testen, weil das bei vielen Performance-Reports als Alternative genannt wird (unabhängig von einander). So hatte ich lighttpd+FastCGI auf Port 81 installiert und auf die identische Code-Basis losgeschickt. Der Benchmark ergab: Keine Verbesserung.
Nun, nach ein paar weiteren Bedenk-Tagen bin ich zu der festen Überzeugung gekommen, dass das Problem im Drupal zu finden war. So habe ich nach weiterem Literaturstudium hatte ich dann den entscheidenden Tipp gefunden: http://civicactions.com/blog/2009/feb/10/profiling_drupal.
So kopierte ich die gesamte Drupal-Installation auf mein Notebook (zur Vereinfachung der ganzen Sache), installierte “xdebug“http://www.xdebug.org/, aktivierte das Generieren von Profiling-Informationen und installierte kcachegrind (KDE, Linux). Und ziemlich schnell war klar, dass der Performance-Engpass durch das Modul og_content_type_admin verursacht wurde, welches in hook_init jedes mal die Funktion “menu_router_rebuild” aufruft. Als ich diesen Aufruf testweise auskommentierte, hatte ich kein Performance-Problem mehr!
Ein nochmaliger Benchmark lieferte überzeugende Ergebnisse:
# ab -n50 -c2 -dS http://portal.firma.de/node/111
...
Connection Times (ms)
min avg max
Connect: 90 105 148
Processing: 1279 1470 2139
Total: 1369 1575 2287
Mit 1,5 Sekunden Seiten-Ladezeit kann ich sehr gut leben :)
Das Problem ist den Entwicklern übrigens bekannt, allerdings ist das Ticket geschlossen und die vorgeschlagene Lösung hat bei mir keine Verbesserung gebracht. So habe ich mich von der Funktionalität leichten Herzens getrennt.



Wow.
Das nenne ich mal einen eindrucksvollen Blogbeitrag!
Kannst du Kcachegrind noch etwas genauer erklären, vorallem wie man die xdebugDaten dort hereinbekommt.
Man bin ich froh dass es solche genialen Tools für Linux gibt :)
hm… ich sehe schon, ich muss mich wohl doch auch in linux ein wenig einarbeiten, denn für windows gibt es keinen php profiler :(
Xdebug gibt es wohl für Windows, das Profiling kannst Du in der php.ini konfigureren. Unter Linux werden die cachegrind*-Dateien im Ordner /tmp abgelegt. ich habe sie sicherheitshalber in meinen Heimat-Ordner kopiert. Und mit WinCacheGrind gibt es auch ein Windows-Programm dafür. Allerdings erscheint mir (bein Ansehen des Screenshots Kcachegrind “zielführender” zu sein.
Aber ich kann Dir 63 andere Gründe nennen, warum es sich lohnt in Linux einzuarbeiten ;-)
Viele Grüße, Dirk
D.
Always borrow money from a pessimist; he doesn’t expect to be paid back.
Xdebug legt per Default die Profiling-Daten in /tmp ab. Das lässt sich aber auch über Properties in php.ini anpassen. Ich habe mir die Dateien gleich ins Heimat-Verzeichnis kopiert, um sie nach dem nächsten Reboot noch da zu haben.
@dereine: Über KCachegrind werde ich einen eigenen Beitrag schreiben und Dich dann anpingen :)
Ich habe da eine Kategorie Projekt des Monats, die unbedingt Nachschub braucht!
Das Tool hat mich nachhaltig beeindruckt. Schlüssel zum Glück ist das Tool valgrind und die Tool-Suite drum herum, die auch das Profiling für andere Arten von Anwendungen (klassische Desktop/Server-Anwendungen) anbietet.
Viele Grüße, Dirk
D.
Always borrow money from a pessimist; he doesn’t expect to be paid back.
Laut Bugtracking sollte das Problem ja behoben sein, gibt es dazu weitere Informationen?
Nein, ich habe mich zwischenzeitlich auf der Website komplett von OG getrennt und auf Foren gesetzt (weil die Leute damit besser umgehen konnten). Auf einer anderen Seite habe ich OG im Einsatz, aber nicht in der Konfiguration. Also: Nix neues.
D.
Always borrow money from a pessimist; he doesn’t expect to be paid back.