NoSQL: Key-Value-Datenbank Redis im Überblick

Werkzeuge  –  Kommentare

In der Datenbank-Community wird seit geraumer Zeit das Schlagwort "NoSQL-Datenbanken" intensiv diskutiert. Unter diesem Oberbegriff existiert eine Reihe von Datenbanken unterschiedlicher Zielsetzung. Mit Redis sei im Folgenden ein Vertreter der Key-Value-Stores vorgestellt, die der NoSQL-Gemeinde zugerechnet werden. Am Beispiel des Spring Data Project wird zudem ein erstes Framework vorgestellt, mit dem sich Redis ohne direkten Zugriff auf die Low-Level-API in Java-Projekte einbinden lässt.

Zahlreiche Datenbanken lassen sich mittlerweile der wachsenden "NoSQL-Gemeinde" zuordnen. Ein guter Marktüberblick befindet sich unter nosql-database.org. Obwohl die verfügbaren Systeme sich in ihren theoretischen Grundlagen unterscheiden, zielen alle auf ähnliche Projektanforderungen im Hinblick auf Skalierbarkeit, verteilte Datenhaltung und flexible Speichermodelle für Dateninhalte des Web-2.0-Zeitalters. NoSQL-Datenbanken lassen sich in vier Gruppen einteilen: KeyValue-Stores sowie spaltenorientierte, dokumentenorientierte und Graphendatenbanken.

Die "einfachste" Form stellen die Key-Value-Stores dar, die die zu speichernden Daten immer nur in Form eines Key-Value-Paars ablegen. Der Schlüssel verweist dabei auf einen (meist in Binär- oder Zeichenketten-Format vorliegenden) Wert. Die Einfachheit, die sich vom Grundprinzip her nicht wesentlich von einer Ablage in Betriebssystemdateien unterscheidet und die seit vielen Jahren in Embedded-Datenbanken wie Oracles Berkeley DB zur Verfügung steht, lässt sich nun auch über "standalone" NoSQL-Datenbanken einsetzen.

Möchte man die Anwendungsgebiete für Key-Value-Datenbanken erfahren, orientiert man sich am besten direkt am Titel "Key-Value". Wenn es um die Ablage und Abfrage von Daten in immer derselben Form geht – nämlich "Speichere einen Datensatz zu einer gegebenen ID" beziehungsweise "Lese exakt diesen Datensatz zur gegebenen ID", ohne dass der Datensatz noch komplex mit anderen Daten verbunden werden soll -- und die Anzahl solcher Operationen hoch werden kann, sollte man sich Key-Value-Datenbanken ansehen. Ein Beispiel ist die Sessionverwaltung in einem Websystem. Über einen Key (etwa aus einem Cookie-Wert) hinterlegt man den aktuellen Zustand einer Websession und kann ihn dadurch bei späteren Zugriffen auslesen und überschreiben.

Die Einfachheit des Datenmodells erleichtert die Skalierbarkeit dieser Systeme, sodass Letzteres bei großen Datenmengen das Hauptargument für den Einsatz von Key-Value-Datenbanken ist.

Ein Beispiel für eine solche Datenbank ist Redis (Remote Dictionary Server), ein Open-Source-Projekt, das seit März 2010 zusammen mit seinem "Erfinder" Salvatore Sanfilippo im Hause VMware beheimatet ist. Redis ist eine in C implementierte "single-threaded" In-Memory-Datenbank. Wer bereits mit dem Memory-Caching-System Memcached gearbeitet hat, wird die Ähnlichkeit mit Redis erkennen. Aber Redis bietet mehr als Memcached,nämlich nicht "nur" die Speicherung von Strings, sondern auch komplexereDatentypen wie Listen, Mengen und seit Version 2.0 auch Hashes. Als In-Memory-Datenbank hält Redis alle Daten im Hauptspeicher, der über Virtual Memory erweiterbar ist, in den sich dann seltener benutzte Value-Datensätze auslagern lassen.

Im Falle eines Serverabsturzes bedeutet eine solche Hauptspeicherablage die Gefahr eines Datenverlusts. Um die Gefahr zu minimieren, bietet Redis unterschiedliche Mechanismen an. Entweder schreibt die Datenbank alle Daten zyklisch auf Platte (Default) oder man wählt den "Append Only Mode", der nur die Befehle, die zur Rekonstruktion des Datenbestands nach einem Systemcrash erforderlich sind, in ein Logfile schreibt. In beiden Fällen lässt sich nach einem Systemabsturz der Datenbestand (fast) vollständig wiederherstellen, im Falle des "Append Only"-Modus jedoch mit höherem Zeitaufwand.

Durch die Einfachheit des Datenmodells gehören Projekte mit komplexen Datenstrukturen eher nicht zur Redis-Zielgruppe. Stattdessen konzentrieren sich die Redis-Entwickler auf eine schnelle Verarbeitung einfach strukturierter Daten. Wer die Performance selber testen will, findet im Redis-Paket vorbereitete Benchmark-Skripte, mit denen er die auf der Webseite beschriebenen Werte auf seiner eigenen Rechnerkonfiguration verifizieren kann. Auf eine Besonderheit wird man beim Studium der Performanceergebnisse schnell stoßen: In der Datenbank sind Schreib- in der Regel schneller als Leseoperationen.

Seit Ende Februar 2011 liegt Redis 2.2 vor. Schwerpunkt dieser Version waren zahlreiche Verbesserungen beziehungsweise Fehlerbeseitigungen bei bestehenden Funktionen, etwa im Bereich Speicheroptimierung und Performancesteigerungen.

Starten mit Redis kann man entweder über den von anderen Produkten bekannten Weg (Download, Installation, Start) oder über die für die Einarbeitung entwickelte Website try.redis-db.com, die neben einem umfangreichen Online-Tutorial Mittel zur Verfügung stellt, um aktiv mit einer Redis-Instanz zu kommunizieren.

Die Einarbeitung in das Thema Redis erfolgt meist mit dem Ausprobieren einiger grundlegender Redis-Befehle. Die beiden wichtigsten lauten

set <key> <value>

und

get <key>

die man wie folgt direkt an eine Redis-Datenbank senden kann:

redis>  SET erster_schluessel "Hello World"
OK
redis> GET erster_schluessel
"Hello World"
redis>

Danach stellt sich relativ schnell die Frage, wie man Redis innerhalb eines Projekts als Datenbank verwenden kann, also für welche Programmiersprachen es APIs gibt. Die Redis-Webseite führt zu der Frage zahreiche Projekte auf, die solche Programmierschnittstellen für beinahe alle wichtigen Sprachen (etwa C/C++, C#, Java, Perl, PHP, Python und Scala) zur Verfügung stellen. Für den Einsatz mit Java ist beispielsweise JRedis geeignet. Der einfache Set- und Get-Zyklus aus obigem Beispiel sieht mit JRedis wie folgt aus:

JRedis  jredis = new JRedisClient(); // Default-Werte fuer Host 
// (localhost) und Port (6379)
jredis.set("erster_schluessel", "Hello World");
System.out.println(jredis.get("erster_schluessel"));

An dem kleinen Codebeispiel erkennt man aber den Nachteil, den solche APIs haben: die hart kodierten Abhängigkeiten des verwendeten Frameworks und der eingesetzten Datenbank. Will man zu einem späteren Zeitpunkt das Framework und/oder die Datenbank wechseln, sind die entsprechenden Sourcecode-Anteile umzuschreiben. Um solchen Problemen vorzubeugen, setzt man in Java beispielsweise in Verbindung mit relationalen Datenbanken meist auf Standards wie JDBC (Java Database Connectivity) oder JPA (Java Persistence API). Hält man sich dabei streng an den Standard und meidet herstellerspezifische Erweiterungen, sollte ein Wechsel der JDBC- beziehungsweise JPA-Implementierung und/oder ein Wechsel der darunterliegenden Datenbank einfach durch Austausch der zugehörigen Treiber-Bibliotheken im Classpath der Java-Anwendung zu realisieren sein. Gesucht ist also für NoSQL-Datenbanken im Allgemeinen und Redis im Speziellen eine Art "JDBC für NoSQL-Datenbanken".