Probleme mit libmemcached und PECL memcached Inkompatibilität
Da wir uns bei mail.de wunderten warum eines unserer Preload-Scripte nicht so funktioniert wie es sollte, habe ich gestern und heute mehrere Stunden damit zugebracht herauszufinden woran das liegt.
Das Preload-Script ist eine Art Warmup-Script, es lädt gewisse Daten in den Memcached-Server die kurz darauf benötigt werden (könnten). Das Preload-Script läuft mittels Gearman auf eigenen Maschinen, getrennt von den Apache-Webservern.
Da wir neue Features erstmal in einer Umgebung testen die der Live-Umgebung sehr ähnlich ist (wir nennen sie PreLive, andere nennen sie staging), fiel uns da auf dass das Preloading nicht so funktionierte wie gewünscht. Auf unseren Entwicklermaschinen und in der kleinen lokalen Testumgebung ist es nicht aufgefallen da dort beides nicht getrennt ist.
Trotz Preloading, sprich die Daten sollten bereits im Memcached liegen wenn sie gebraucht werden, war die entsprechende Funktion auf dem Webserver langsam, und wie wir herausfanden wurden die Daten nicht aus dem Memcached geholt da sie dort nicht vorhanden waren. Wir prüften natürlich zuerst ob der Preload-Mechanismus überhaupt griff und das entsprechende Script die Daten in den Memcached legte. Das war der Fall.
Auf der Suche nach dem Fehler schrieb ich einige Testscripte, die mit festgelegten Keys Daten in den Memcached legte und wieder ausgelesen sollte. Doch interessanterweise war Key1, der auf einem Gearman-Server in den Memcached gelegt wurde, auf den Apache-Servern nicht verfügbar. Zuerst dachten wir an unterschiedliche Einstellungen, wir überprüften IP-Adresse, PREFIX_KEY, php.ini Einstellungen etc., aber nichts zu finden. Es machte einfach keinen Sinn.
Der einzige Unterschied konnte noch das PECL memcached Modul sein, und siehe da, auf den Gearman-Servern war bereits memcached 2.0.1(mit libmemcached 0.47) installiert, auf den Apache-Servern noch memcached 1.0.2 (libmemcached 0.47). Ein Upgrade der PECL-Extension auf 2.0.1 behob den Fehler.
Auf den Live-Servern sah es ähnlich aus: Gearman-Server hatten die 2.0.1 installiert, und die Apachen noch 1.0.2. Update auf 2.0.1 gemacht, dann sollte es funktionieren. Doch es ging natürlich nicht. Bei näherer Betrachtung fiel auf dass die verwendeten libmemcached-Versionen nicht übereinstimmten, die Gearman-Server hatten die Version 0.47 installiert, die Webserver 0.50. Also die libmemcached-Versionen auch angeglichen und schon funktionierte alles wie gewünscht.
Das Problem bestand also aus 2 Gründen: selbst bei gleicher libmemcached-Version funktionierte es nicht wenn die PECL memcached-Extension unterschiedlich war. Und selbst bei gleicher Extension-Version funktionierte es nicht wenn die libmemcached-Versionen nicht übereinstimmten.
Die Versionen sind bei Standardeinstellungen anscheinend nicht kompatibel. Leider kann ich aus dem Changelog bzw. den Announcements von libmemcached nicht erkennen dass es da eine Inkompatibilität gibt. Auf der Suche nach dem Changelog bin ich auf eine interessante Seite gestossen die versucht die Rückwärtskompatibilität anzuzeigen. Beim PECL-Paket könnte man erahnen dass es vielleicht an der neu hinzugefügten fastlz-Komprimierung liegt die seit der 2er Version Standard ist, und die die 1er Version nicht kennt.
Für die Zukunft heißt es also, immer die selben PECL-memcached-Versionen zu nutzen und auch überall die selben libmemcached-Versionen auf allen beteiligten Servern zu installieren, damit so etwas nicht noch mal passieren kann.
Ohne jeden Zweifel ärgerlich. Aber zwischen 1.0.2. und 2.0.1 sind wohl doch schon einige Versionen released worden. Einfach nicht Up2Date gewesen *kidding*
Sebastian
20 Jun 12 at 16:29
Vielen Dank für die Information!
Daniel
20 Jun 12 at 16:36
Also bei zwei verschiedenen Major Versions kanns ich die inkompatibilität ja verstehen bei der PECL Extension.
Andererseits nutzt ihr libmemcached nicht einmal in einer stabilen Version 1.x, wodurch ich auch da mit inkompatibilitäten rechnenwürde.
Alles in allem nichts unegwöhnliches auf Software seite.
PS: libmemcached ist bei euch aber auch mit Version 0.50 ziemlich veraltet. Ein Blick in die Doku zeigt, dass diese für 1.0.6 erstellt wurde.
Dennis Becker
21 Jun 12 at 13:05
Ja, das ist uns auch klar geworden dass wir da nicht ganz up2date waren. Aber so veraltet nun auch wieder nicht, libmemcached 0.50 ist von Juni 2011, also gerade 1 Jahr alt. Version 1.0.2 ist im Oktober erschienen.
PECL memcached 1.0.2 war bis März diesen Jahres die aktuellste stable, auch da hingen wir nicht so weit hinterher.
So alt ist das alles gar nicht. Trotzdem hätte eine Dokumentation der Änderung bei libmemcached geholfen bei der Suche 😉
Michael Kliewe
21 Jun 12 at 14:55