Im Laufe der Zeit habe ich die verschiedensten Caching-Methoden ausprobiert, um irgendwelche Web-Applikationen zu beschleunigen. In der Regel will man damit Datenbanken entlasten, vor Allem wenn gleiche Query's tausendfach ausgeführt werden. Allerdings ist es in manchen Fällen so, dass der Aufwand den Nutzen nicht rechtfertigt bzw. sogar die Last durch das Caching höher ist, als durch die ursprünglichen Abfragen. Ich will hier mal am Beispie einer klassischen WebApp mit MySql-Backend ein paar Caching-Varianten samt meinen Erfahrungen darstellen. Zuerst einmal 2 Methoden, wie man mit MySql-Bordmitteln schon etwas erreichen kann:
Der
MySql Query Cache speichert direkt auf dem MySql-Server die Ergebnisse einzelner Query's und liefert bei erneuter Abfrage nur das Ergebnis aus, ohne die Datenbank selbst erneut zu durchsuchen. Ganz abgesehen von den üblichen Limitierungen wie RAM und Anzahl der Query's im Cache ist das eigentliche Problem hier, dass nach JEDER Änderung in der entsprechenden Tabelle (INSERT/UPDATE) die Ergebnisse neu aus der Datenbank gelesen werden müssen (siehe z.B.
hier). Somit fällt für mich der dieser Cache maximal unter "nice to have". Eine unter Last stehende Datenbank (in die meistens auch immer UPDATES oder INSERTS kommen) kann er aber wohl kaum entlasten ...
Eine weitere Alternative sind
Tabellen vom Typ MEMORY. Leider unterstützt MEMORY keine BLOB- oder TEXT-Spalten, was sie z.B. für Volltextsuchen ungeeignet macht. Dennoch sind sie eine gute Alternative, wenn der DB-Server aufgrund vieler komplexer Abfragen sehr häufig auf die Festplatte zugreifen muss. Für Session-Tabellen beispielsweise ziemlich gut geeignet. Man sollte allerdings nicht vergessen, dass die Last nicht gänzlich vom DB-Server weggenommen wird, schließlich muss er die Anfragen weiterhin beantworten. Auch spielt natürlich der auf DB-Servern meist nur wenig vorhandene, freie RAM eine Rolle.
Caching-Methoden, die sich außerhalb des SQL-Servers abspielen:
Zuerst einmal gibt es natürlich
Flatfiles, also einfache
Textdateien, in denen man temporäre Daten als Cache ablegen kann. Bei kleinen Ergebnismengen, keiner hohen Last auf dem jeweiligen System und ausreichender Plattenkapazität kann auch dies einen Gewinn bringen. Allerdings ist es oft nicht sehr elegant zu bewerkstelligen, die alten Files zeitnah zu löschen bzw. vorhandene Files zu aktualisieren. Ein Cronjob kann da z.B. natürlich Abhilfe schaffen, man sollte aber die Limitierungen des jeweiligen Filesystems im Bezug auf maximale Ordner- und Datenanzahl nicht vergessen. Außerdem steigt die Load auf einem Server sehr schnell an, wenn diese Files sehr oft und zahlreich geöffnet/geschlossen werden. Auch
ulimit kann hier eine Rolle spielen, sofern zu klein gesetzt.
Dann gibt es natürlich noch
SQLite, was sich z.B. für kleinere Sachen als Auslagerung sehr gut eignet. Allerdings stößt man bei größeren Sachen schnell an die Filesystem-Grenzen, außerdem hatte ich in meinem Anwendungsfall mit recht hoher Last auf dem System zu kämpfen, wenn sehr viele Abfragen (nur SELECT's) auf die SQLite-DB's eingingen (Zugriff via PHP/PERL). Da war in diesem Fall sogar dann die Speicherung in Flatfiles effektiver. Außerdem hat man wieder das Problem mit der Wartung, denn man muss dafür sorgen, dass in den SQLite-DB's stets halbwegs aktuelle Informationen aus der MySql-DB liegen - je nach Notwendigkeit.
Nun kommen wir zu meinem klaren Favoriten
memcached. Ich habe es selbst zigfach im Einsatz und bin einfach begeistert. Vor Allem die eingebaute TTL ist wunderbar, so muss man sich nicht darum kümmern, alte Einträge mühsam zu entfernen etc. Auch läuft memcached sehr stabil, verbraucht quasi null Rechenleistung und kann wunderbar hunderte Anfragen parallel bearbeiten. Ein besseres Caching-System kann man sich kaum wünschen. Allerding sollte man die Limitierung von maximal 1 MByte je Objekt beachten. In der Praxis stößt man aber nur sehr selten an diese Grenze. API's für die gängigen Scriptsprachen stehen bereit, so dass man seine WebApp damit recht einfach mit effektivem Caching versehen kann. Natürlich braucht man, je nach gewünschter TTL und Menge der Objekte entsprechend Server mit viel freiem RAM. Ansonsten ist memcached eine klare Empfehlung! Ein weiterer Vorteil ist, dass selbst bei einem Ausfall des memcached-Servers die Applikation weiterläuft, nur eben ohne Caching. Dank der Möglichkeit, memcached-Server verteilt aufzubauen, sollte das aber i.d.R. nicht vorkommen.
Natürlich macht es nicht in jedem Fall Sinn, einen Cache zu verwenden. Wenn man eine Website mit 20 Besuchern am Tag hat, kann man sich beispielsweise getrost lieber SEO widmen als Caching

Auch bei sich permanent ändernden Anfragen/Ergebnismengen macht ein Cache wohl kein Sinn. Aber überall, wo sich Anfragen über einen recht kurzen Zeitraum zigfach gleichen und die Last auf der Datenbank recht hoch ist, macht ein Cache vielleicht durchaus Sinn. Wichtig ist auch, dass die Infrastruktur noch fähig sein sollte, auch ohne den Cache auszukommen (bzw. den Ausfall zu kompensieren), zumindest teil- oder zeitweise.
Nachdem sich memcached offenbar immer größerer Beliebtheit erfreut und auch das kürzlich stattgefundene MySql-Webcast "Bereitstellung von Web-2.0-Anwendungen mit MySQL und Memcached" im Anschluss sehr viele User-Fragen hervorrief, habe ich im Adminwiki ma
Aufgenommen: Dec 23, 14:13