29. Juni 2008

Trennung von Memcache und Web Server

Memcache (memcached) nimmt meiner Datenbank fantastisch viel Arbeit ab. Alle Objekte sind im Memcache, kein Code greift direkt auf die Datenbank zu. Die Datenbank wird dadurch um eine Größenordung entlastet. Was die Datenbank leisten müsste sieht man dann, wenn der Cache leer ist. Dann geht alles direkt auf die DB bis der Cache wieder gefüllt (warm) ist.

Der Memcache ist ein verteilter Speicher. Er ist verteilt über mehrere Rechner. Will man keine Rechner extra für den Memcache abstellen, dann verwendet man traditionell die Webserver auch als Memcache-Server. Das heißt nicht, dass es schneller wird, weil die meisten Zugriffe nicht lokal sind, aber billiger weil man keine extra Rechner braucht. Die Webserver hat man ja sowieso. Die Standardvorgehensweise ist also: 10 Webserver hinter einem Loadbalancer. Auf jedem Webserver ein memcached. Das wird deshalb empfohlen, weil Webserver vor allem CPU brauchen (CPU bound) und der Memcache vor allem Speicher (memory bound). Man kann also die jeweils "andere" Ressource auch noch nutzen.

Soweit die Standardvorgehensweise. Tatsache ist aber, dass bei PHP/Apache basierten Webservern (LAMP!) Webserver meistens auch memory bound sind. Apache und PHP werden nämlich normalerweise im Prefork-Modus verwendet. Also viele Apache Prozesse, jeder mit einer eigenen PHP-Runtime. Bei einer großen Applikation braucht ein so ein Apache/PHP Prozess schnell mal 16 MB Speicher. Der geteilte Speicher der verwendeten DLLs fällt kaum ins Gewicht. Das sind fast alles Daten. Ein Standardserver vom letzen Jahr hat 2 GB Speicher, 2 Cores. Will man 100 Apache Prozesse laufen lassen, bekommt man 16 MB x 100 = 1,6 GB. Da bleibt nicht mehr viel für den Memcache, der auch sein 1 GB pro Rechner haben sollte. Schließlich sind ja 1 Mio. User und zig Millionen Objekte im Cache. Dieses Jahr sind es 4 GB und 4 Cores, aber man erwartet auch 200 Prozesse pro Rechner, also auch nicht besser. Apache und Memcache konkurrieren um den Speicher.

Und es wird noch schlimmer. Apache und Memcache haben in der Standardkonfiguration unterschiedliche Verfügbarkeitsanforderungen. Webserver hinter dem Loadbalancer können ab und zu mal ausfallen. Der Loadbalancer merkt das schnell und nimmt sie aus dem Lastverteilungsverbund. Alle Daten, alle Sessions sind im Memcache und damit stets transferierbar. Aber: vom Memcache-Verbund darf kein einziger Rechner ausfallen. Selbst wenn man das schnell merkt und ihn aus dem Verbund nimmt, bedeutet der Ausfall eines einzigen Memcache-Servers einen 50% Cache-Flush. Memcache-Clients berechnen aus dem Key und den verfügbaren Memcache-Servern auf welchem Server die gefragten Daten liegen und holen sie direkt dort. Fällt ein Server aus, dann ändert sich die Zuordnung der Keys zu den Memcache-Servern. Die Daten bleiben dort gespeichert, aber die Clients finden sie nicht mehr und nehmen an, dass sie nicht da sind. Es gibt alternative Zuordnungsalgorithmen, die verhindern, dass sich alle Keys umsortieren. Das ist bitter nötig in großen Memcache-Clustern (Facebook: man spricht von 800 Rechnern mit viel Speicher). Denn dann fällt immer einer aus oder es kommt einer dazu.

Aber trotzdem reicht das nicht, denn Webserver sind manchmal überlastet und fallen für den Loadbalancer effektiv aus. Wenn auf dem gleichen Rechner ein memcached läuft und der auch nicht mehr antworten kann, dann fällt ein Teil (20% oder 10%) des Caches aus. Das treibt die Datenbank sofort zu Höchstleistungen und propagiert das Überlastproblem vom Frontend-Rechner zur DB. Das kann schnell die Performance des Gesamtsystems zerstören. Denn braucht die DB 1 h bei leerem Cache um den Cache zu füllen, dann führt der Ausfall von 1 aus 5 Memcaches immerhin zu 1h / 5 = 12 Minuten Überlast auf der DB. Das hört sich nicht gut an, denn eigentlich ist es das Ziel überhaupt keine Spannungssituationen zu erzeugen bloß weil ein Webserver ausfällt.

Webserver arbeiten viel mit der Festplatte. Das ist im high-performance Bereich auch zu vermeiden, aber ist trotzdem Standard im Medium-Segment. Geht die Festplatte kaputt steht der Webserver. Memcache arbeitet nur mit Speicher, überhaupt nicht auf der Platte. Steht die Platte kann er weiterarbeiten. Es ist unsinnig den Memcache von der Festplatte des Webservers abhängen zu lassen. Eigentlich sollte der Memcache-Server vom Netz booten und ohne Platte arbeiten. Ein Teil weniger was kaputt gehen kann, und zwar das häufigste.

Webserver und Memcache haben sehr unterschiedliche Profile und sollten deshalb nicht die Rechner teilen. Webserver (sollen nicht, aber) dürfen ausfallen, deshalb Software RAID-1. Memcaches (tun es, aber) dürfen nicht ausfallen, deshalb entweder RAID-Controller, damit die Platte im Betrieb getauscht werden kann oder gar keine Platte. Webserver so bemessen, damit sie CPU und Speicher Last tragen können. Separate Memcache-Server bemessen, so dass alle zusammen alle Daten der Applikation speichern können, die innerhalb der TTL der Cache-Items anfallen.

happy_coding()

Kommentar veröffentlichen