Partnerwahl

Nachdem alle Daemons in Stellung gebracht sind, entscheidet man sich für eine der zahlreichen Client-Bibliotheken. Diese gibt es mittlerweile für zahlreiche Programmier- und Skriptsprachen, teilweise besteht sogar die Wahl zwischen verschiedenen Paketen [2]. Wer lieber seinen eigenen Client zimmern möchte, findet eine ausführliche Beschreibung des zugrunde liegenden Protokolls unter [3].

Da Memcached in der Praxis häufig Web-Anwendungen beschleunigt, dürfte die Wahl meist auf einen PHP-Client fallen. Da diese Sprache zudem auch ohne weitere Vorkenntnisse verständlich ist, kommt sie bei allen nachfolgenden Beispielen zum Einsatz. C- und C++-Programmierer finden mehr Informationen im Kasten "libmemcached". Die grundlegende Vorgehensweise ist in allen Sprachen gleich: Nachdem die passende Client-Bibliothek gefunden und installiert ist, bindet der Entwickler sie zunächst in das eigene Programm ein. Mit PHP und dem »memcache« -Client aus dem PECL-Repository, wie er auch Ubuntu im Paket »PHP5-memcache« beiliegt, erstellt diese Zeile ein neues »Memcached« -Objekt:

$memcached = new Memcached;

Anschließend teilt ein Funktionsaufruf der Bibliothek mit, auf welchen Servern überhaupt Memcached-Daemons warten:

$memcache->connect('192.168.2.1', 11211) or↩
 die ('Keine Verbindung zu memcached Server');

Ab jetzt können weitere Funktionsaufrufe den Cache nach Lust und Laune mit eigenen Informationen bestücken:

$memcache->set('schluessel', 'test', false,↩
 10);

Diese Anweisung schiebt die Zeichenkette »test« unter dem Schlüsselwort »schluessel« in den Cache, wo sie für 10 Sekunden liegen bleibt. Die Schlüssellängen sind übrigens derzeit auf maximal 250 Zeichen begrenzt – eine Limitierung, die vom Memcached-Daemon ausgeht.

Um wieder an die Daten heranzukommen, gibt man bei der Client-Bibliothek wieder den Schlüssel ab und fängt das zurückgeworfene Ergebnis auf:

$result = memcache->get('schluessel');

Listing 1 zeigt noch einmal das komplette PHP-Skript.

Listing 1

Eine einfache Cache-Abfrage in PHP.

<?php
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ('Keine Verbindung zu memcached Server');
$memcache->set('schluessel', 'datum', false, 10);
$result = $memcache->get('schluessel');
var_dump($result);
?>

libmemcached

Die derzeit beliebteste Client-Bibliothek für C-und C++-Anwendungen heißt »libmemcached« [4] – nicht zu verwechseln mit dem eingestampften Vorgänger »libmemcache« (ohne d am Ende). Selbst wer weder in C noch C++ programmiert, sollte einen Blick in das Paket riskieren, da es ein paar interessante Kommandozeilenwerkzeuge zur (Server-)Diagnose enthält. So holt beispielsweise »memcat« die Daten zu einem Schlüssel aus dem Cache und gibt sie auf der Konsole aus, während sich »memstat« nach dem aktuellen Zustand eines oder mehrerer Server erkundigt. Zur Übersetzung von »libmemcached« muss auf dem System neben dem C-, auch ein einsatzbereiter C++ Compiler installiert sein, den Rest erledigt wieder »./configure; make; make install« . Eine einfache Cache-Abfrage geschieht dann wie folgt:

#include <memcached.h>
#include <string.h>
#include <stdio.h>
main()
{
        /* memcached_st Struktur anlegen (enthält alle grundlegenden Infos über die memcached Server) */
        memcached_st *mcd = memcached_create(NULL);
        /* Einen Server hinzufügren: */
        memcached_server_add(mcd, "127.0.0.1", 11211);
        /* Objekt in den Cache schieben: */
        char *key = "schluessel";
        size_t keylength = strlen(key);
        char *value = "information";
        size_t valuelength = strlen(value);
        time_t expiration = 0;
        uint32_t flags = 0;
        memcached_add(mcd, key, keylength, value, valuelength, expiration,flags);
        /* Objekt wieder rausholen: */
        memcached_return fehlervariable;
        char *result = memcached_get(mcd, key, keylength, &valuelength, &flags, &fehlervariable);
        /* Objekt ausdrucken: */
        printf("Cache: %s\n", result);
        /* Aufräumen: */
        memcached_free(mcd);
}

Besonders interessant ist die Möglichkeit, mehrere Daten gleichzeitig sowohl in den Cache zu schreiben, als auch wieder auszulesen. Die Client-Bibliothek parallelisiert dabei automatisch ihre Anfrage an die Memcached-Server. Leider stellen nicht alle Client-Bibliotheken diese Funktionen zur Verfügung, das folgende Beispiel klappt beispielsweise unter PHP nur mit dem Memcached-Client (mit dem "d" am Ende):

$mehrere = array(
        'schluessel1' => 'wert1',
        'schluessel2' => 'wert2',
        'schluessel3' => 'wert3'
);
$memcache->setMulti($mehrere);

Ihr Einsatz, bitte

Bei bestehenden Web-Anwendungen stellt sich schnell die Frage, an welchen Stellen man Memcached am besten nachträglich einbaut und nutzt. Die Antwort liefert ein kleines Profiling: Alle Datenbankabfragen, die den Server besonders stressen, leitet man in den Cache um. Wie so etwas in der Praxis aussieht, zeigen Listing 2 und 3: Vor der Datenbankabfrage prüft der Code, ob die gesuchten Informationen nicht in Memcached liegen. Nur wenn dieser kein passendes Objekt liefert, erfolgt einer Abfrage der Datenbank. Um sich beim nächsten Mal eine weitere Abfrage zu sparen, speichert man ihre Ergebnisse noch rasch in den Cache. Um diesen stets auf dem aktuellen Stand zu halten, wandern bei jedem Schreibvorgang auf die Datenbank die dabei fließenden Informationen auch noch in den Cache. In Listing 3 setzen sich die Schlüssel übrigens aus dem Wort »user« und der ID des Benutzerkontos zusammen – eine weit verbreitete Strategie, um eindeutige Schlüssel zu erhalten.

Listing 2

Datenbankabfrage ohne Memcached…

function get_user($userid)
{
        $result = mysql_query("SELECT * FROM users WHERE userid = '%s'", $userid);
        return $result;
}

Listing 3

… und nach seiner Anwendung

$memcache = new Memcache;
$memcache->connect('servername', 11211) or die ('Keine Verbindung zu memcached Server');
...
function get_user($userid)
{
        $result = memcache->get("user" + $userid);
        if(!$result)
        {
                $result = mysql_query("SELECT * FROM users WHERE userid = '%s'", $userid);
                memcache->add("user" + $userid, $result);
        }
        return $result;
}

Mit diesem Vorgehen ist Memcached schnell in die eigenen Anwendungen integriert. Das Cache-System weist allerdings auch ein paar Fußangeln auf, die sich erst bei einem Blick unter die Haube offenbaren.

Ähnliche Artikel

comments powered by Disqus

Artikel der Woche

Eigene Registry für Docker-Images

Wer selber Docker-Images herstellt, braucht auch eine eigene Registry. Diese gibt es ebenfalls als Docker-Image, aber nur mit eingeschränkter Funktionalität. Mit einem Auth-Server wird daraus ein brauchbares Repository für Images. (mehr)
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Ausgabe /2021