Mit der Zeit fanden wir heraus, dass dies wohl am eaccelerator liegt, worauf wir XCache versuchten, was anfangs einen besseren Eindruck machte. Nach 2-3 Tagen Betrieb unter Hochlast, trat wieder das selbe Problem auf.
Nach langem Suchen durch diverse Foren und Blogs, fand ich heraus, dass dies keine unbekannten Probleme sind, die einfach auf Bugs in diesen Opcode Cachern (eaccelerator und XCache) zurückzuführen sind und man solle doch APC (Alternative PHP Cache) nutzen.
Freudig stellte ich fest, dass APC nicht mehr bei jedem Update selbst kompiliert werden musste (phpize, configure, make, make install), sondern einfach via apt-get zu beziehen ist (unter Debian/Lenny, noch nicht unter Etch), das Paket nennt sich “php-apc”. Nicht, dass ich das Selbstbauen scheue, aber bei über 20 Webservern, die teilweise 32, teilweise 64 Bit Kernel haben, ist man froh, wenn man sich diese Arbeit sparen kann.
Nun läuft APC auch noch seit Wochen ziemlich stabil, ab und zu tritt noch ein 500er auf, aber dies hat andere Gründe (lighttpd backend overloaded), an denen wir arbeiten. Die APC-Config basiert auf den Standardwerten, abgesehen von “apc.stat_ctime”, welches auf 1 gesetzt ist, da der Cacher sonst nicht mit Dateiaktualsierungen via SVN klarkommt.
Performancetechnisch ist bis jetzt kein Nachteil gegenüber den beiden Konkurrenzprodukten festzustellen.
Weiterhin spricht die Tatsache, dass es offiziell von den PHP-Entwicklern supportet wird, ebenfalls für APC.
Fazit: Was spricht gegen APC? Warum werden so oft eaccelerator und XCache genutzt, obwohl es sich bei beiden noch um Beta-Versionen handelt (Version < 1)?
Hintergrundinfo (alles Lenny Pakete):
- php-apc Version: 3.0.19-2
- php-cgi Version: 5.2.6.dfsg.1-1+lenny2
- lighttpd Version: 1.4.19-5
2. Problem (daraus resultierend):
die “alten” php-cgis greifen gemeinsam mit den neuen auf den eaccelerator cache zu. Wird dieser dann noch geleert, wird er aus irgendeinem Grund nicht mehr aufgebaut und der Webserver läuft ohne eaccelerator und wirft in regelmäßigen Abständen 500er Fehler.
Alles in allem, nicht sehr schön. Nun haben wir aber eine Lösung gefunden:
Die lightys werden nicht neugestartet, sondern erst gestoppt, dann wird ein killall -9 php-cgi ausgeführt, 2 Sekunden gewarten, dann nochmal den killall Befehl abgesetzt und zuletzt wird lighty wieder gestartet.
Bis jetzt sind wir mit dieser Lösung recht zufrieden, auch wenn es ein wenig länger dauert, alle 18 lightys durchzustarten.
Würde gerne wissen, warum lighty nicht in der Lage ist, alle php-cgi Prozesse zu killen, bevor er sich wieder startet.
]]>
eAccelerator ist ein sogenannter Opcode-Cacher, er kompiliert die PHP Skripts beim ersten Aufruf und legt die Binaries in seinen Cache. Beim nächsten Aufruf muss nun nicht mehr neu kompiliert werden (wie es normalerweise üblich wäre für PHP), sondern es kann auf den Cache zurückgegriffen werden.
Zuletzt trat der Fehler erst gestern Abend auf, 6 Stunden nachdem eine Änderung des Codes erfolgte (eine Codeänderung führt auch gleichzeitig zu einem Neustart der Lightys). Nach längerer Loganalyse konnten wir diesen Fehler im error.log von lighttpd finden:
EACCELERATOR: PHP crashed on opline 10 of getNamespaceByKey() at /var/www/(…)/memcache_manager.php:431
Auf anderen Weberservern trat dieser Fehler ebenfalls zum gleichen Zeitpunkt hunderfach auf (teilweise an anderen Codestellen). Im syslog trat gleichzeitig ein anderer Fehler auf:
php-cgi: PHP Fatal error: Call to undefined function MemcacheManager::() in /var/www/(…)/memcache_manager.php on line 375
Da wir nicht nachvollziehen können, warum dieser Fehler auftritt, gibt es nun 2 Workarounds. Das erste verhindert schlimmeres, indem alle lightys vor der Peaktime der Seite einfach durchgestartet werden (inkl. Cacheleerung).
Das zweite ist ein Cronjob, der jede Minuten das lighty-error-log parsed und nach entsprechenden Stellen in der letzten Minute sucht, trat tatsächlich ein solcher Fehler auf, wird der lighty durchgestartet und wir per Mail informiert.
Solange ich keine Antwort auf der eAccelerator Mailingliste bekomme und keine neue Version von eAccelerator erscheint, müssen wir wohl vorerst auf diese Workarounds zurückgreifen, auch wenns nicht wirklich schön ist.
]]>Nach langer Recherche im Internet und überprüfung der Paketversionen, viel auf, dass das PHP-Memcache Paket eine komplette Versionsnummer weiter war (statt 2.x nun 3.x).
In der Dokumentation bzw. dem Changelog fand ich dann zwei Gründe, für unsere Probleme.
Nachdem beides geändert wurde, lief es auf dem Testserver optimal, selbiges wurde dann noch auf den Produktivservern umgesetzt. Nachdem wir dann, anhand überdurchschnittlicher CPU Load, bemerkten, dass der Opcode-Cacher eaccelerator noch neu Kompiliert werden musste (logisch eigentlich), lief alles wieder einwandfrei.
]]>