====== Remote Dictionary Server ====== Redis (kurz für Remote Dictionary Server) ist ein OpenSource Datenbank-System. Durch seine [[http://de.wikipedia.org/wiki/NoSQL|No-SQL]]-Beschaffenheit widerspricht es dem gängingen Konzept einer relationalen Datenbank, mit der via [[dbs:sql:start|SQL]] kommuniziert wird. Redis gehört zur Familie der [[http://de.wikipedia.org/wiki/In-Memory-Datenbank|In-Memory-Datenbanken]]. Das bedeutet, dass sich der Datenbestand im Hauptspeicher befindet. Daten werden durch eine einfache Schlüssel-Wert-Struktur erfasst und in [[struct:hash:start|Hash-Tables]] organisiert. Somit wird ein Wert mit einem Schlüssel identifiziert. Die Datenbank funktioniert somit wie ein großes Wörterbuch. ==== Vorteile ==== Da sich alle Daten im Hauptspeicher befinden, können Zugriffe auf indizierte Daten sehr schnell erfolgen. Laut [[http://de.wikipedia.org/wiki/Redis|Wikipedia-Artikel]] können mit Redis bis zu ca. 100.000 Schreibvorgänge und ca. 80.000 Lesevorgänge pro Sekunde durchgeführt werden. Diese Werte liegen deutlich über denen gängiger relationalen Datenbanksystemen wie [[dbs:mysql:start|MySQL]]. Auch auf herkömmlicher Hardware (z.B. gängige Desktop-PCs) ist dieser Geschwindigkeitsvorteil merkbar. ==== Nachteile ==== Die Schlüssel-Wert-Architektur eignet sich prinzipiell für einfache Datenstrukturen. Für die Abbildung komplexerer Strukturen ist Redis nur bedingt geeignet; dazu müssen diese aufwändig auf die Schlüssel-Wert-Struktur abgebildet werden. Ein größerer Nachteil liegt im Fehlen der Persistenz. Da sich alle Daten im Hauptspeicher befinden gehen sie prinzipiell verloren, wenn der Redis-Server oder das ganze System neugestartet werden. Allerdings bietet Redis die Möglichkeit den Datenbestand beispielsweise zyklisch auf die Festplatte zu sichern. Für [[http://de.wikipedia.org/wiki/ACID|ACID-konforme Systeme]] ist Redis jedoch nicht geeignet. ====== Installation ====== Redis ist OpenSource und kann auf der [[http://redis.io/download|offiziellen Projekt-Seite]] heruntergeladen werden. Im Folgenden wird die Installation auf linux-basierten Systemen mittels [[make:start|Makefile]] beschrieben. Nachdem das Archiv heruntergeladen und entpackt wurde (z.B. nach ''/opt/redis'') kann es mittels make all kompiliert werden. Anschließend stehen im Verzeichnis src/ die Programme ''redis-server und redis-cli'' zur Verfügung. Um den Server bzw. CLI-Client bequem starten zu können, bietet sich die Erstellung eines Shell-Skripts an: **/usr/sbin/redis-server** #!/bin/bash cd /opt/redis/src ./redis-server & Nachdem das Skript mit chmod +x /usr/sbin/redis-server (als root) ausführbar gemacht wurde, kann der Redis-Server mittels ''redis-server'' gestartet bzw. mit ''killall redis-server'' beendet werden. **/usr/sbin/redis-cli** #!/bin/bash cd /opt/redis/src ./redis-cli Ebenfalls mit chmod +x /usr/sbin/redis-cli (als root) kann der CLI-Client ausführbar gemacht und mit ''redis-client'' gestartet werden. Der Umgang mit dem interaktiven CLI-Client wird im kommenden Abschnitt erklärt. ====== Interaktiver Client ====== Mit ''redis-cli'' kann der interaktive CLI-Client gestartet werden. Wer sich zunächst erst an Redis ausprobieren möchte, ohne etwas zu installieren, kann [[try auf http://try.redis.io/|Try Redis]] online ausprobieren. Redis unterstützt folgende Datentypen: ==== String ==== ==== List ==== ==== Hash ==== ==== Set ==== ==== Sorted Set ==== ====== Verwendung ====== ==== Beispiel-Datenbank ==== Wer bisher mit relationalen, SQL-kompatiblen Datenbanken gearbeitet hat, "denkt" bereits relational. Im Folgenden werde ich **eine** Möglichkeit zeigen, wie eine einfache relationale Datenbank auf eine Redis-Datenbank abgebildet werden **könnte**. Dabei handelt es sich um eine Möglichkeit von sicherlich vielen. Tabelle Account Primärschlüssel ID (int) E-Mail-Adresse (varchar) Passwort (varchar) Mentor (Fremdschlüssel auf Account) In Redis ließe sich dies abbilden, indem kombinierte Schlüssel verwendet werden. Dabei werden atomate Informationen (E-Mail-Adresse, Zeitstempel, Betreff usw.) hinter eingenständigen Schlüssel gespeichert. So beschreiben folgende Schlüssel die nebenstehenden Werte: * ''account:0:email'' beschreibt die E-Mail-Adresse (''String'') des Accounts mit der ID 0. * ''account:17:pwd'' beschreibt das Passwort (''String'') des Accounts mit der ID 17. * ''account:12:mentor'' beschreibt den Mentor (Primärschlüssel des beziehnden Accounts ''String'') des Accounts mit der ID 12 * usw. Dadurch können zunächst automate Werte gespeichert und geladen werden: > set "account:0:email" "foo@bar.com" OK > set "account:17:pwd" "secret123" OK > get "account:0:email" "foo@bar.com" Das Einfügen eines Neuen Datensatzes ''Account("wiki@proggen.org", "zugeheim1337")'' mit **neuem** Primärschlüssel ist beispielsweise folgendermaßen möglich: > incr "account_id" (integer) 2 > sadd "accountss" 2 (integer) 1 > set "account:2:email" "wiki@proggen.org" OK > set "account:2:pwd" "zugeheim1337" OK Dabei erhöht ''inc'' den Wert von ''account_id''. Existiert ''account_id'' nicht, wird der Wert 1 verwendet. Mittels ''sadd'' fügen wir den Primärschlüssel ''2'' zur Menge ''accounts'' hinzu. Wollen wir später alle Accounts ermitteln, macht diese Menge über die aktuell verwendeten Primärschlüssel eine klare Aussage. Dies setzt natürlich voraus, dass wir beim Entfernen des Datensatzes ebenfalls diesen Index aktualisieren. ==== Beispiel in Python ==== Ubuntu-basierte Systeme können das Paket ''python-redis'' installieren. Dieses Binding wird im folgenden Beispiel verwendet. import redis server = redis.Redis("localhost") def add(email, pwd): # get next primary key account_id = server.incr("account_id") server.sadd("accounts", account_id) # add account key_for_email = "account:%i:email" % account_id key_for_pwd = "account:%i:pwd" % account_id server.set(key_for_email, email)): server.set(key_for_pwd, pwd) return account_id def delete(account_id): # delete primary key server.srem("accounts", account_id) # delete account key_for_email = "account:%i:email" % account_id key_for_pwd = "account:%i:pwd" % account_id server.delete(key_for_email server.delete(key_for_pwd) Natürlich fehlt das Arbeiten mit den Rückgabewerten, d.h. wenn ''server.sadd'' fehlschlägt würde dennoch der Datensatz hinzugefügt. Für das prinzipielle Verständnis der Arbeit mit Redis ist dies jedoch nicht primär. Sollen nun Login-Daten geprüft werden, bietet sich eine Indizierung der E-Mail-Adresse an, d.h. hinter den Schlüssel ''account:EMAIL::id'' könnte der Primärschlüssel hinterlegt werden. Dies bietet sich beispielweise bei Registrierungen an, um die Vergabe der E-Mail-Adresse eindeutig zu machen (so dass sie nicht mehrfach verwendet werden kann). Diese und weitere Details bzw. Verhaltensweisen lassen sich mit Redis nachbilden. ==== Beispiel in C++ ==== ==== Beispiel in PHP ====