- 1 Section
- 10 Lessons
- unbegrenzt
- NoSQL – MongoDB, Redis & Grundlagen10
Redis-Anwendungsfälle: Cache, Session, Pub/Sub
In Lektion 7 haben wir Redis kennengelernt – ein In-Memory-Key-Value-Store mit ultraschnellen Zugriffszeiten. Jetzt schauen wir, wofür man das in der Praxis nutzt. Redis ist selten die primäre Datenbank einer Anwendung; viel öfter ist es eine Ergänzung zu einer SQL-DB oder MongoDB, die für spezifische Probleme verwendet wird.
Diese Lektion zeigt die fünf wichtigsten Anwendungsfälle: Cache, Session-Store, Pub/Sub-Messaging, Rate-Limiting und Queue/Job-Verarbeitung. Wer eine dieser Aufgaben hat und sie ohne Redis löst, schreibt fast immer eine schlechtere Version dessen, was Redis von Haus aus mitbringt.
1) Use Case 1: Cache (mit Abstand am häufigsten)
Der Klassiker: deine SQL-Datenbank ist langsam, weil komplexe JOINs oder Aggregationen Zeit kosten. Statt jedes Mal die DB zu fragen, speicherst du das Ergebnis in Redis mit einer TTL – beim nächsten Zugriff kommt es aus dem Cache. Das nennt man Cache-Aside-Pattern (oder „Lazy Loading"):
function getProduct(id):
# 1) Erst im Cache schauen
cached = redis.get("product:" + id)
if cached: return JSON.parse(cached) # Cache Hit
# 2) Sonst aus DB lesen
product = db.query("SELECT * FROM products WHERE id = ?", id)
# 3) In Cache schreiben mit TTL (5 Minuten)
redis.setex("product:" + id, 300, JSON.stringify(product))
return product
Wichtige Caching-Patterns: Cache-Aside (App liest aus Cache, fällt auf DB zurück – siehe oben), Write-Through (Schreibvorgänge gehen erst in Cache, dann synchron in DB), Write-Behind (asynchron in DB). Cache-Aside ist am häufigsten – einfach und tolerant gegen Cache-Ausfälle.
2) Use Case 2: Session-Store
HTTP ist zustandslos – aber Web-Anwendungen brauchen Zustand: „eingeloggter User", „Warenkorb-Inhalt", „letzte Suche". Klassisch wurden diese Sessions im Server-Speicher gehalten, was aber bei mehreren Servern hinter einem Load Balancer Probleme macht („sticky sessions"). Mit Redis als zentralem Session-Store ist das egal:
SET session:abc123xyz '{"userId":42,"name":"Anna","cart":[...]}' EX 1800
OK
# Bei jeder weiteren Anfrage: Token validieren + Session laden
GET session:abc123xyz
'{"userId":42,"name":"Anna","cart":[...]}'
# Inaktivitäts-Timer zurücksetzen bei jeder Anfrage
EXPIRE session:abc123xyz 1800
# Beim Logout
DEL session:abc123xyz
Eleganz: die TTL ist der eingebaute Auto-Logout. Nach 30 Minuten Inaktivität ist die Session weg – ohne Cron-Job zum Aufräumen. Beim Logout reicht ein DEL. Die Frameworks der meisten Sprachen (Express, Django, Spring) haben Redis-Session-Provider eingebaut.
3) Use Case 3: Pub/Sub – Messaging zwischen Services
Redis bietet ein einfaches Publish/Subscribe-System: ein Service publiziert Nachrichten auf einen Channel, mehrere Services können diesen Channel abonnieren und bekommen die Nachrichten live. Klassisch für Event-getriebene Architekturen, Mikroservices, Live-Updates auf Webseiten:
orders
SUBSCRIBE channel zum Abonnieren, PUBLISH channel message zum Senden. Wichtig: Pub/Sub in Redis ist fire-and-forget: gibt es keine Abonnenten zum Zeitpunkt des PUBLISH, ist die Nachricht weg. Für robuste Messaging-Systeme mit Persistenz nimmt man Redis Streams (seit Redis 5) oder spezialisierte Brokers wie RabbitMQ oder Kafka.4) Use Case 4: Rate Limiting
„Maximal 100 Anfragen pro Minute pro IP" – das ist Rate Limiting, eine Standard-Anforderung an APIs. Mit Redis ist das in vier Zeilen erledigt. Der Trick: pro IP gibt's einen Counter mit TTL von der gewünschten Zeitspanne:
function checkRate(ip):
key = "ratelimit:" + ip
current = redis.incr(key) # atomarer Inkrement
if current == 1:
redis.expire(key, 60) # erst beim ersten Setzen TTL
if current > 100:
return "429 Too Many Requests"
return "OK"
5) Use Case 5: Queue / Job-Verarbeitung
Wenn ein Web-Request etwas Langsames auslöst (E-Mail senden, Bild prozessieren, Report generieren), willst du den Nutzer nicht warten lassen. Stattdessen schiebst du den Job in eine Queue, ein Background-Worker holt sich Jobs raus und verarbeitet sie. Redis-Listen sind dafür ideal:
RPUSH jobs:email '{"to":"...","subject":"...","body":"..."}'
(integer) 5 # Queue-Länge nach Push
# Im Worker-Prozess: Jobs blockierend holen
BLPOP jobs:email 30
# blockiert max. 30 Sek bis ein Job kommt, dann zurück:
1) "jobs:email" 2) '{"to":"...","subject":"...","body":"..."}'
Schön an BLPOP: der Worker blockiert effizient bis ein Job kommt – kein Busy-Waiting mit ständigen Polls. Mehrere Worker können dieselbe Queue gleichzeitig konsumieren – Redis garantiert, dass jeder Job nur einmal abgegeben wird. Für komplexere Queue-Funktionalität (Retries, Delays, Prioritäten) gibt es Frameworks wie Bull (Node.js), Sidekiq (Ruby), Celery (Python) die intern Redis nutzen.
6) Use Case 6: Leaderboards (mit Sorted Sets)
Ein Spiel zeigt die Top-10-Spieler nach Punkten. In SQL wäre das ein SELECT … ORDER BY score DESC LIMIT 10 – aber bei Tausenden gleichzeitigen Updates wird die DB schnell zum Bottleneck. Redis Sorted Sets sind dafür gemacht:
ZADD leaderboard 2500 "player_anna"
ZADD leaderboard 1800 "player_tim"
ZADD leaderboard 3200 "player_lisa"
# Top 3 Spieler (absteigend)
ZREVRANGE leaderboard 0 2 WITHSCORES
1) "player_lisa" 2) "3200"
3) "player_anna" 4) "2500"
5) "player_tim" 6) "1800"
# Rang eines spezifischen Spielers (1-basiert, von oben)
ZREVRANK leaderboard "player_anna"
(integer) 1 # 0-indexiert, also Platz 2
Updates und Top-N-Abfragen sind in Sorted Sets logarithmisch (O(log N)). Selbst bei Millionen Spielern bleibt das schnell. Für Multi-Game-Leaderboards einfach unterschiedliche Schlüssel verwenden: leaderboard:racing, leaderboard:shooter, etc.
7) Weitere Use Cases im Überblick
SET key value NX EX 30 erstellst du einen Lock mit Auto-Ablauf. Klassisch für „nur ein Worker darf diesen Job ausführen".SINTER berechnet die Schnittmenge zweier Sets.INCR ist viel schneller als ein UPDATE in der SQL-DB.8) Wann Redis NICHT die Lösung ist
Trotz aller Begeisterung – Redis ist nicht für alles geeignet. Drei Anti-Patterns:
- Als primäre Datenbank für transaktionale Daten: Bestellungen, Buchungen, Rechnungen gehören in eine SQL-DB mit vollen ACID-Garantien. Redis bietet zwar einfache Transaktionen, ist aber nicht für komplexe Geschäftsdaten gebaut.
- Für sehr große Datenmengen: Redis hält alles im RAM. Bei mehr als ein paar hundert GB wird das teuer und unpraktisch. Für solche Datenmengen sind Wide-Column-Stores oder klassische Disk-basierte DBs die richtige Wahl.
- Wenn Datenverlust unter keinen Umständen akzeptabel ist: Selbst mit AOF-Persistenz kann Redis bei einem Crash die letzten Schreibvorgänge verlieren. Für Audit-Logs, Banktransaktionen, kritische Daten: bleib bei einer DB mit echten Durability-Garantien.
Zusammenfassung
Redis wird selten als primäre DB eingesetzt – meist als Ergänzung für spezialisierte Use Cases. Die wichtigsten: Cache (Cache-Aside-Pattern mit TTL, entlastet die Haupt-DB drastisch), Session-Store (zentral statt sticky sessions, mit TTL als Auto-Logout), Pub/Sub (Event-Distribution zwischen Services, fire-and-forget), Rate-Limiting (per-User/IP Counter mit TTL, ein paar Zeilen Code), Queue/Jobs (Listen mit BLPOP für effizientes Worker-Pattern), Leaderboards (Sorted Sets, logarithmisch schnell). Auch: distributed locks, Tag-Suche, Counter, HyperLogLog, Geo-Queries, Feature Flags. Nicht für: primäre transaktionale Daten, Datenmengen jenseits weniger hundert GB, harte Durability-Anforderungen. Faustregel: jede Anforderung mit hoher Frequenz und Toleranz für gelegentlichen Datenverlust ist ein Kandidat für Redis. Die Entscheidung zwischen SQL und NoSQL – inklusive Redis – ist Thema der nächsten Lektion.
