Archive for the ‘Technisches’ Category

Warum Caching mit Memcached toll ist

Samstag, September 20th, 2008

MySQL ist toll, denn es kann

  • Benutzerauthentifizierung mit Rechtekonzept
  • diverse Storage-Engines
  • Caching für diverse Dinge
  • verschiedene Indextypen
  • Volltextsuche
  • JOINs
  • umfangreiche Möglichkeiten der Selektion (WHERE-Bedingungen)
  • Sortierung der Daten
  • Recovery
  • Transaktionen
  • Locking

Gar nicht übel, oder?
Aber eigentlich sollte es doch um Memcached gehn. Was ist also so toll an Memcached?
Er kann von alle dem nichts und genau das ist seine Stärke:
Im Gegensatz zur (vergleichesweise langsamen) eierlegenden Wollmilchsau MySQL kann Memcached genau eine Sache: Daten (nicht persistent) speichern.
Dazu wird ein Server, der eigentliche Memcached, benötigt, auf welchen dann mit einer der zahlreichen Client-Libraries zugegriffen werden kann.
Bevor man loslegt sollte man sich zunächst über ein paar Besonderheiten klar werden:

  • Es gibt keine Zugriffskontrolle: Wer auf den Port verbinden kann, kann auch alle Daten auf dem Server lesen/schreiben – IpTables sind also Pflicht
  • Die Daten werden nur im RAM gehalten, sind also nach einem Neustart weg. Memcached ersetzt also keinesfalls eine Datenbank
  • Auf die Daten kann nur mittels eines eindeutigen Schlüssels zugegriffen werden. Iterieren ist nicht möglich
  • Die verschiedenen Client-APIs sind i.d.R. nicht kompatibel. Was man z.B. mit Perl schreibt, kann man mit PHP vermutlich nicht lesen
  • Memcached ist SCHNELL!

Sobald man das verdaut hat, kann man sich Gedanken darüber machen, wie man das nutzen kann.

Beispiel aus dem echten Leben (Der Zugriff erfolgt über PHP und mit dem prozeduralen Interface – Nähere Infos bei PHP.net):
Wir haben mehrere Millionen Gästebucheinträge von denen immer die X aktuellsten auf dem Profil des jeweiligen Benutzers angezeigt werden. Bei jedem Profilaufruf müssen also aus diesen Millionen Einträgen die Einträge des Profilbesitzer herausgesucht, chronologisch sortiert und dann ausgegeben werden. Das geht mit MySQL wunderbar, verbrät aber logischerweise einiges an Resourcen. Da Gästebücher aber wesentlich öfter gelesen, als geschrieben werden, bietet sich hier der Einsatz von Memcached an:
Beim Aufruf der Seite versucht man zunächst mittels memcache_get($connection, $gaestebuchid); die Einträge aus dem Cache zu lesen, falls das klappt ist alles bestens und man kann sie ausgeben ohne den MySQL-Server belästigen zu müssen. Werden die Einträge nicht gefunden, dann liest man die Daten ganz normal aus der Datenbank und schreibt sie anschließend mittels memcache_set($connection, $gaestebuchid, $gaestebuchArray); in den Cache, so dass sie (hoffentlich) beim nächsten Aufruf verfügbar sind. Wenn man dann noch daran denkt mittels memcache_delete($connection, $gaestebuchid); den Cacheeintrag zu löschen, wenn ein neue Eintrag hinzukommt/sich etwas ändert, dann hat man schon seinen ersten, wirkungsvollen Cachingmechanismus mittels Memcached implementiert.

Zweites Beispiel:
Um die Anzahl der eingeloggten Benutzer anzuzeigen müssen bei uns die MySQL-Tabelleneinträge der User gezählt werden, deren letzte Aktivität mehr als X Minuten zurück liegt. Da sich diese Zugriffzeit sehr häufig ändert (nämlich mit jedem Klick des Benutzers) wäre es sehr ineffizient einen Index auf die entsprechenden Spalte zu legen, was aber zu folge hat, dass MySQL jeden einzelnen Tabelleneintrag durchgehn (Table-scan) und die gespeicherte Zeit mit dem Timeout vergleichen muß, was widerrum natürlich sehr aufwändig ist.
Mit Memcached wird auch das besser: Man prüft zunächst wieder mit memcached_get ob die aktuelle Nutzerzahl schon im Cache steht, falls ja, gibt man diese aus, falls nicht muß doch wieder der MySQL-Server herhalten. Anschließend speichert man den Wert natürlich im Cache. Würde man das aber mit einem simplen memcache_set($connection, ‘onlineuser’, $onlineuser); machen, so würde man für die komplette Laufzeit des Cache-Servers die gleiche Onlineuserzahl geliefert bekommen (weil das get jedesmal erfolgreich wäre und der SQL-Server nie mehr befragt würde). Deshalb gibt es die Möglichkeit Memcached-Einträgen einen Timeout zu verpassen. Mittels memcache_set($connection, ‘onlineuser’, $onlineuser, 0, 60); würde dieser z.B. auf 60 Sekunden festgesetzt. Nach dieser Zeit findet man im Cache keine Onlineuserzahl mehr, so dass der SQL-Server wieder befragt wird und die Zahl sich somit minütlich erneuert.

Wie man hoffentlich deutlich erkennen kann zeigt Memcached seine Stärke nur in Verbindung mit einer Datenbank im Hintergrund. Er kann (und will) also einen Datenbankserver nicht ersetzen, aber er kann auf erstaunlich einfache Weise helfen selbigen zu entlasten.

Sollte noch jemand interessante Praxisbeispiele oder Ergänzungen haben, würde ich mich freuen darüber in den Kommentaren zu lesen.

Servermonitoring mit Munin

Mittwoch, April 9th, 2008

Mal wieder ein technischer Artikel. Diesmal zum Thema Servermonitoring
(mehr …)

Beitragsbewertung

Donnerstag, Februar 28th, 2008

Ich habe bei Mathias Bank (Grüße aus Ulm nach Ulm ;-)) vom WP PostRating-Plugin gelesen. Ich fand die Idee ganz lustig und hab das Plugin gleich mal testweise Eingebaut.
Das Ganze ist leider noch auf englisch, sollte aber wohl trotzdem verständlich sein 😉

MySQL-Backups mittels LVM Snapshots

Samstag, Februar 23rd, 2008

Wie versprochen folgt nun ein Einblick in die Welt der MySQL Backups. Wer keine Lust auf technisches Blabla hat, der kann sich diesen Eintrag hier schenken, denn davon gibts hier einiges 😉
(mehr …)

Infrastruktur

Sonntag, Februar 17th, 2008

Ich will in nächster Zeit einen etwas detaillierteren Überblick über die Technik im Hintergrund und vor allem über unsere Erfahrungen damit geben.
Für den Anfang gibt es erstmal einen kurzen Überblick über die verwendete Software:

Richtig los geht es demnächst mit einem Artikel über MySQL und Datenbankbackups.