Zum Inhalt
wannacode

Key-Value und der Cache

Kurz gesagt: Ein Key-Value-Store wie Redis ist ein Wörterbuch im Arbeitsspeicher, das zu einem Schlüssel sehr schnell den Wert liefert. Deshalb eignet er sich als Cache, für Sitzungen und für Zähler.

Problem

Die Seite, die tausendmal dasselbe fragt

Die Startseite des Shops zeigt die drei meistverkauften Produkte. Das ist die Abfrage:

SQLDatenbank: Shop

Sie verbindet drei Tabellen und addiert alle Bestellzeilen. Bei 2000 Besuchen pro Minute führt die Datenbank sie 2000-mal aus, obwohl sich die Antwort nur alle paar Stunden ändert. Auch der Warenkorb und der Login fragen bei jeder Seite die Datenbank dasselbe. Du brauchst einen Ort, an dem die fertige Antwort in einem Bruchteil einer Millisekunde geholt wird.

Die Idee

Ein Schlüssel und ein Wert

Eine Key-Value-Datenbank ist ein Wörterbuch: Jeder Wert hat einen Schlüssel, und du bekommst ihn über den Schlüssel. Es gibt keine Tabellen, keine Spalten und keine Abfragen nach dem Wert. Deshalb ist sie so schnell: Redis hält alles im Arbeitsspeicher und antwortet in Mikrosekunden.

Das Feld ist ein Simulator mit den Redis-Befehlen. Schlüssel schreibt man meist mit Doppelpunkten, damit klar ist, was darin steckt:

Key-Value (wie Redis)Simulator

GET auf einen Schlüssel, den es nicht gibt, liefert (nil). Der Wert ist Text, auch wenn er eine Zahl ist: Die Datenbank weiß nicht, dass 7.90 ein Preis ist.

Probier es aus

Ein Aufrufzähler

INCR erhöht die Zahl in einem Schlüssel um 1 und gibt die neue zurück. Gibt es den Schlüssel nicht, beginnt er bei 0. Zwei Seiten, die gleichzeitig zählen, kommen sich nicht in die Quere: Jeder Befehl in Redis läuft bis zum Ende, bevor der nächste beginnt.

Produkt 7 wurde dreimal angesehen und Produkt 9 einmal. Zähle die Aufrufe in den Schlüsseln views:product:7 und views:product:9.

Key-Value (wie Redis)Simulator

Die Idee

Ein Cache, der abläuft

Ein Cache ist eine Kopie einer Antwort, deren Berechnung teuer ist. Das Programm schaut zuerst in den Cache. Ist dort nichts, fragt es die Datenbank und legt die Antwort für eine festgelegte Zeit (EX in Sekunden) im Cache ab. Diese Zeit ist die TTL (time to live, Lebensdauer), und TTL zeigt, wie viel noch übrig ist:

Key-Value (wie Redis)Simulator

Nach 60 Sekunden verschwindet der Schlüssel von selbst, und der nächste Besuch fragt wieder die Datenbank. So ist der Cache nie älter als eine Minute, und die Datenbank führt die Abfrage einmal pro Minute aus, nicht 2000-mal.

Genauer, für Neugierige

SLEEP ist nur ein Befehl des Simulators: Er stellt dessen Uhr vor, damit du nicht wirklich wartest. Im echten Redis vergeht die Zeit einfach. Der Simulator sortiert die Antwort von SMEMBERS und KEYS alphabetisch, während Redis überhaupt keine Reihenfolge verspricht. Und KEYS führt man nicht auf einem echten Server mit Millionen Schlüsseln aus: Der Befehl geht sie alle durch und blockiert jeden anderen Befehl. Dort nimmt man SCAN.

Sieh es dir an

Die veraltete Kopie

Der Preis des Kaffees sinkt von 14,90 € auf 12,90 €. Die Datenbank ist aktualisiert, aber der Cache hält die alte Seite noch 10 Minuten lang:

Key-Value (wie Redis)Simulator

Das ist der häufigste Fehler mit einem Cache: Die Kopie weicht von der Wahrheit ab. Deshalb löscht das Programm, das das Produkt in der Datenbank ändert, sofort seine Kopie im Cache (DEL). Der nächste Besuch findet nichts, fragt die Datenbank und speichert den neuen Preis. Die TTL bleibt als Sicherheitsnetz, falls du es mal vergisst.

Probier es aus

Ein neuer Preis für den Käse

Im Cache liegen die Seiten des Weißkäses (Produkt 7) und der Butter (Produkt 9). Der Preis des Käses hat sich gerade in der Datenbank geändert. Sorge dafür, dass der nächste Besuch beim Käse den neuen Preis bekommt, ohne die Butter anzufassen.

Key-Value (wie Redis)Simulator

Die Idee

Nicht nur Text

Ein Wert in Redis kann auch eine Struktur sein. Jede hat ihre eigenen Befehle:

  • Hash (HSET, HGET, HINCRBY, HGETALL): Felder unter einem Schlüssel, wie ein Warenkorb mit einem Produkt und einer Menge;
  • Liste (LPUSH, LRANGE, LTRIM): geordnete Werte, wie die zuletzt angesehenen;
  • Sorted Set (ZADD, ZINCRBY, ZREVRANGE): Mitglieder mit einem Score, danach geordnet, wie eine Bestenliste.

Der Warenkorb von Kunde 42 (Produkt 9, Butter, zwei Stück, und Produkt 5, Milch, eins), der nach einer Woche ohne Aktivität abläuft:

Key-Value (wie Redis)Simulator

Die letzten drei angesehenen Produkte. LPUSH stellt vorne ein, und LTRIM schneidet alles nach dem dritten ab:

Key-Value (wie Redis)Simulator

Die im Oktober verkauften Stück, in einer Rangliste:

Key-Value (wie Redis)Simulator

Bei gleichem Score ordnet Redis die Mitglieder alphabetisch (hier umgekehrt, weil die Bestenliste von oben nach unten geht).

Übung

Eine Sitzung, ein Warenkorb und eine Bestenliste

1. Kunde 42 meldet sich an. Die Seite gibt ihm die Sitzungsnummer 9f2c und merkt sich in Redis, wer er ist.

Speichere die Nummer des Kunden (42) im Schlüssel session:9f2c, sodass die Sitzung nach 30 Minuten von selbst abläuft.

Key-Value (wie Redis)Simulator

2. Der Warenkorb von Kunde 7 liegt im Hash cart:7: Das Feld ist die Produktnummer, der Wert die Menge.

Kunde 7 legt 2 Packungen Butter (Produkt 9) und 1 Milch (Produkt 5) in den Warenkorb. Dann fügt er noch eine Butter hinzu und entfernt die Milch.

Key-Value (wie Redis)Simulator

3. Der Schlüssel rating enthält die Durchschnittsbewertung jedes Produkts.

Zeige die drei Produkte mit der höchsten Bewertung zusammen mit den Bewertungen, von der höchsten abwärts.

Key-Value (wie Redis)Simulator

Die Idee

Wann Key-Value, wann nicht

Eine Key-Value-Datenbank ist gut, wenn du den Schlüssel immer kennst: ein Cache, Sitzungen, Warenkörbe, Zähler, Rate Limiting („höchstens 5 Anmeldeversuche pro Minute“), Warteschlangen für Aufgaben. Sie ist nicht gut, wenn du nach dem Wert fragst („alle Produkte unter 5 €“), wenn die Daten verbunden sind („die Bestellungen des Kunden mit ihren Produkten“) und wenn ein Verlust nicht in Frage kommt. Deshalb steht sie meist neben der SQL-Datenbank, nicht an ihrer Stelle: Die Datenbank ist die Wahrheit, und Redis ist ihre schnelle Kopie.

Genauer, für Neugierige

Neben Redis (und Valkey, das dazu kompatibel ist) sind Key-Value-Datenbanken zum Beispiel Memcached (nur ein Cache, ohne Strukturen), DynamoDB in AWS (mit einem Schlüssel und einem Sortierschlüssel, auf der Platte, verteilt) und etcd (für Cluster-Einstellungen, mit Fokus auf Konsistenz). Redis hält die Daten auf zwei Arten auf der Platte: ein Snapshot alle paar Minuten (RDB) oder ein Protokoll jedes Befehls (AOF).

Test

Teste dich

1. Was lässt sich in einer Key-Value-Datenbank NICHT tun, ohne alle Schlüssel zu lesen?
2. Die Liste der Bestseller liegt 60 Sekunden im Cache. Was kostet das?
3. Der Preis des Kaffees hat sich in der Datenbank geändert. Was ist für den Cache am sichersten?
4. Redis hält die Daten im Arbeitsspeicher. Was passiert bei einem Neustart?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·