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()

27. Juni 2008

Danke Adobe für TCP Port 843

Vor ein paar Tagen den ersten erntzunehmenden Konkurrenten von weblin entdeckt: ROCKETON. Der ROCKETON ist im in Flash 9 programmiert und ROCKETON schreibt, dass man Port 843 outgoing öffnen muss.

Von der Hilfeseite: "Since our application uses Adobe Flash, we must abide by their security policy. In order for Adobe Flash to work in a multiuser environment, you must have port 843 open. Please ask your system administrator to make sure port 843 is not being blocked."

Auf Port 843 liegt ein Policyfile für Flash. Die Datei muss jeder anbieten, der mit Flash 9 Socketverbindungen zu anderen Hosts benutzen will. Das Policyfile muss auf dem Server liegen zu dem verbunden werden soll und zwar auf Port 843. Nu ist mir nicht ganz klar warum ROCKETON Socketverbindungen benutzt, da ROCKETON eigentlich HTTP-long-polling verwendet, aber sie werden es schon wissen.

Was mich aber wieder einmal gewundert hat ist der Port 843, den Adobe für Flash 9 erfunden hat. Klar, mit Socketverbindungen kann man allerhand Unfug treiben. Java benutzt ja auch das für Security eigentlich ungeeignete DNS, um Applets nicht auf beliebige Adressen verbinden zu lassen. Dass das nur ehrliche und hart arbeitende Normalbürger behindert, aber nicht echte Schlimmfinger ist inzwischen bekannt (Stichwort: DNS Rebinding Attacks). Flash dagegen läßt sogar Verbindungen zu anderen Rechnern zu, aber nur wenn dort das Policyfile verfügbar ist. Leider liegt das Policyfile nicht auf den üblichen Ports 80 oder 443. Diese Ports sind meistens offen, haben schon einen Webserver und man müsste nur eine Datei hinlegen. Nein, man muss extra ein Programm laufen lassen auf Port 843, das die Datei hergibt. Und noch schlimmer: der Port ist in Firmen-Intranets meistens nicht offen. Das heißt, Software in Flash 9, die im Labor und bei normalen Benutzern geht, versagt typischerweise im Büro von Kooperationspartnern und Journalisten. D.h. immer wenn man im Business-Development jemand eine Vorführung machen will geht es nicht. Zuhause aber schon. Danke Adobe.

Warum ist das so. Warum nicht Port 80? Vermutlich ist es Adobes Absicht, dass Socketconnections im Firmenumfeld nicht gehen, damit Attacken, wie DNS Rebindung und Portscanning nicht funktionieren. Nette Idee, um private Rechner von Firmenrechnern zu unterscheiden, aber irgendwie auch ganz schön doof und vor allem ziemlich nervend, wenn man mit Flash tolle Sachen machen will. Ja, sie können es machen. Flash gehört ihnen und wir müssen es ja auch nicht benutzen. Aber irgendwie habe ich das Gefühl, dass es bessere Schutzmechanismen geben muss, als DNS, Stringvergleiche und gesperrte Ports.