How-To: SQL-Queries cachen (Teil 2: memcached)
10. September 2007 – 17:13Im ersten Teil meines How-To habe ich das Caching von Ergebnissen von SQL-Abfragen mit dem Dateisystem erläutert, jetzt muss der Arbeitsspeicher herhalten ![]()
Ich empfehle den ersten Teil zuerst zu lesen, da ich bei diesem nahtlos anschließe.
Vorteile
Caching im Arbeitsspeicher hat ein paar Vorteile gegenüber dem Dateisystem. Zuerst einmal ist es bequemer mit memcache, da wir uns nicht um die Lebensdauer des Caches kümmern müssen, da der Server dies für uns tut.
Ein weiterer Punkt (weswegen man überhaupt Caching benutzt) ist die Geschwindigkeit. Die langsamste Komponente eines Computers ist meist die Festplatte, der Arbeitsspeicher ist wesentlich schneller. Beim Dateisystem muss das Betriebssystem Daten auf die Festplatte schreiben und später wieder auslesen, also vom Arbeitsspeicher (in dem ja das Skript läuft) auf die Festplatte kopieren und dann wieder zurück. Bei memcache werden Daten vom PHP-Prozess zum memcache-Server geschickt, was wesentlich schneller geht da alles auf einer Ebene abläuft.
Wenn mehrere Server eingesetzt werden kann man mit memcache auch einen gemeinsamen Server für das Caching benutzen. Im normalen Fall müsste man auf einem Server eine Freigabe erstellen auf die alle anderen Server zugreifen können müssten, damit ein zentraler Cache möglich wird. Je nach Netzwerkstruktur und Betriebssystem kann dies schneller oder langsamer sein.
Nachteile
Bei einem Stromausfall verschwindet der Cache im ewigen Datennirvana, was aber zu verschmerzen sein sollte, immerhin ist der Cache ja nur ein Zwischenspeicher.
Installation
Ob es eine Windows-Version von memcache gibt, weis ich nicht, daher gibt’s die Anleitung nur für Linux.
Für alle Befehle benötigt man root-Rechte, bei Ubuntu (und Derivaten) einfach sudo vor die Befehle hängen.
Zuerst einmal benötigen wir den Server memcached:
apt-get install memcached
Danach die passende Erweiterung für PHP:
apt-get install php5-memcache
Nun muss die memcache Erweiterung in der php.ini aktiviert werden:
extension=memcache.so;
Wichtig ist, dass die Variable extension_dir richtig gesetzt ist. Falls PHP die Klasse memcache später nicht findet, ist der Wert wahrscheinlich falsch ![]()
Um herauszufinden welcher Pfad dies sein sollte: einfach locate fragen
michael@michfrm-home:~/Desktop$ locate memcache.so /usr/lib/php5/20060613+lfs/memcache.so
Der erste Test
Zum Testen des Servers verwendete ich eine modifizierte Version vom Orginal Beispiel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // Initalisieren wir ein neues memcache Obkect $memcache = new Memcache; // Und weisen es an, zu einem Server zu verbinden $memcache->connect('localhost', 11211) or die ("Verbindung zu memcache gescheitert!"); // Schauen wir mal, welchen Server wir haben :) $version = $memcache->getVersion(); echo "Server version: {$version}\n"; // Bauen wir uns zum Test eine eigene Klasse class MemTest { public $string; function __construct($string) { $this->string = $string; } } $object = new MemTest('Dies ist ein Test'); // Speichern wir das Objekt im Arbeitsspeicher und lassen es nach 10 Sekunden verfallen echo "Objekt wird gespeichert... "; $memcache->set('key', $object, false, 10) or die ("Speichern des Objekts gescheitert!"); echo "OK!\n"; echo "Objekt wird wieder ausgelesen... "; $mem_object = $memcache->get('key'); echo "OK. Hier das Ergebnis:\n"; var_dump($mem_object); |
Kompletter Quellcode ohne Zeilenummern
Das Ergebnis sollte dann etwa so Aussehen:
Server version: 1.1.12
Objekt wird gespeichert... OK!
Objekt wird wieder ausgelesen... OK. Hier das Ergebnis:
object(MemTest)#3 (1) {
["string"]=>
string(17) "Dies ist ein Test"
}
Wir können also nun Objekte zum Server schicken und wieder holen. Jetzt brauchen wir aber eine nützlichere Anwendung. Wie der Titel schon sage: Cachen von Datenbankergebnissen.
Im folgenden Beispiel wird zuerst versucht die Daten vom memcache Server zu holen. Wenn dieser ein boolsches false zurück liefert, gibt es noch nichts im Cache oder wurde gelöscht weil seine Lebensdauer abgelaufen ist. Falls nichts im Cache ist wird die Datenbank angesprochen (sinnvoll ist auch ein DB-Layer, der erst Verbindungen herstellt wenn nötig, so kann man beim Caching noch mehr Zeit sparen) und die Ergebnisse an memcache gesendet. Danach wird das Ergebnis noch in eine andere Variable referenziert (um Arbeitsspeicher zu sparen) und der weiteren Verarbeitung steht nichts im Weg.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | $mem_key = 'sql_foo'; // Name des Keys $lifetime = 3600; // Eine Stunde haltbar // Schauen wir mal, ob wir was im Cache haben echo "Versuche Daten zu holen\n"; $db_result = $memcache->get($mem_key); if ( $db_result === false ) { echo "Nichts vorhanden, also aus der Datenbank holen\n"; // Nichs gefunden, also holen wir was aus der Datenbank // Irgendwelcher Datenbankkram sollte hier stehen ;) // Nach memcache schicken echo "Schicke Daten zu memcache\n"; $memcache->set($mem_key, $db_values, false, $lifetime) or die ("Konnte nicht cachen\n"); $db_result = &$db_values; // Result richtig zuweisen } // wir brauchen nichts mehr machen, weil wir das Ergebnis ja schon haben :) echo "Das Ergebnis:\n"; var_dump($db_result); |
Kompletter Code ohne Zeilennummern
Viel Spaß beim Ausprobieren! ![]()
3 Kommentare zu “How-To: SQL-Queries cachen (Teil 2: memcached)”
es soll laut php manual auch unter windows funktionieren, nur wie habe ich noch nicht herausgefunden
ich könnte es mir zwar selbst kompilieren, nur ich habe keinen compiler momentan zur hand…
geschrieben von Special-A am 12. Okt, 2007
MinGW (gcc für Windows)
geschrieben von Michael am 12. Okt, 2007
bei xampp für windows wird die memcache.dll mitgeliefert wie ich gerade sehe… man muss diese nur in der php.ini entkommentieren
geschrieben von Special-A am 11. Jan, 2008