Redis Use Cases: Caching, Queues und Rate Limiting

Backend2026-10-06TryQuickToolBox

Sie haben eine Web-App erstellt, die mit einigen Benutzern gut funktioniert, aber mit steigendem Traffic bemerken Sie langsame Seitenladezeiten, doppelte Hintergrundjobs und APIs, die von missbräuchlichen Clients überlastet werden. Dies sind klassische Skalierungsprobleme, die Redis elegant lösen kann. Redis ist ein In-Memory-Datenspeicher, der sich für drei Kernaufgaben hervorragend eignet: Caching, Queues und Rate Limiting. In diesem Artikel erkunden wir jeden Use Case mit praktischen Beispielen und Best Practices.

Warum Redis für diese Use Cases?

Redis speichert Daten im Speicher, was es unglaublich schnell macht – oft mit Antwortzeiten im Sub-Millisekunden-Bereich. Es unterstützt reichhaltige Datenstrukturen wie Strings, Listen, Sets, Sorted Sets und Hashes, die natürlich auf Caching, Queues und Rate Limiting abbilden. Es bietet auch atomare Operationen, Pub/Sub und Persistenzoptionen, was es zu einem vielseitigen Werkzeug für Backend-Entwickler macht.

1. Caching mit Redis

Caching ist der häufigste Redis-Use-Case. Indem Sie häufig abgerufene Daten in Redis speichern, reduzieren Sie die Datenbanklast und beschleunigen Antworten.

Wie Caching funktioniert

Wenn eine Anfrage eingeht, prüfen Sie, ob die Daten in Redis vorhanden sind. Wenn ja (Cache-Hit), geben Sie sie direkt zurück. Wenn nicht (Cache-Miss), holen Sie sie aus der Datenbank, speichern Sie sie in Redis mit einer Ablaufzeit und geben Sie sie zurück. Dieses Muster wird Cache-Aside genannt.

// Node.js Beispiel mit ioredis
const Redis = require('ioredis');
const redis = new Redis();

async function getUser(userId) {
  const cacheKey = `user:${userId}`;
  const cached = await redis.get(cacheKey);
  if (cached) return JSON.parse(cached);

  const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]);
  await redis.set(cacheKey, JSON.stringify(user), 'EX', 3600); // 1 Stunde TTL
  return user;
}

Best Practices für Caching

Cache-Invalidierungsstrategien

Invalidierung ist schwierig. Häufige Strategien sind:

2. Queues mit Redis

Queues entkoppeln zeitaufwändige Aufgaben vom Request-Response-Zyklus. Zum Beispiel können das Senden von E-Mails, die Verarbeitung von Bildern oder die Generierung von Berichten asynchron erfolgen.

Implementierung einer einfachen Queue

Redis-Listen sind perfekt für Queues. Verwenden Sie LPUSH, um Jobs links hinzuzufügen, und BRPOP, um zu blockieren und von rechts zu poppen (FIFO).

// Producer: Job hinzufügen
await redis.lpush('email_queue', JSON.stringify({ to: 'user@example.com', subject: 'Willkommen' }));

// Consumer: Job verarbeiten (in einem Worker)
while (true) {
  const job = await redis.brpop('email_queue', 0); // 0 = unbegrenzt blockieren
  const { to, subject } = JSON.parse(job[1]);
  await sendEmail(to, subject);
}

Zuverlässige Queues mit BRPOPLPUSH

Um den Verlust von Jobs zu vermeiden, wenn ein Worker abstürzt, verwenden Sie BRPOPLPUSH, um den Job atomar in eine Verarbeitungsliste zu verschieben. Nach erfolgreicher Verarbeitung entfernen Sie ihn aus der Verarbeitungsliste. Wenn der Worker stirbt, kann ein anderer Worker Jobs aus der Verarbeitungsliste wiederherstellen.

const job = await redis.brpoplpush('email_queue', 'processing_queue', 0);
try {
  // Job verarbeiten
  await redis.lrem('processing_queue', 1, job);
} catch (err) {
  // Fehler behandeln, eventuell erneut in die Warteschlange stellen
}

Spezialisierte Queue-Bibliotheken

Für den Produktionseinsatz sollten Sie Bibliotheken wie Bull (Node.js), RQ (Python) oder Sidekiq (Ruby) in Betracht ziehen. Sie bieten Wiederholungsversuche, Planung und Monitoring out of the box.

3. Rate Limiting mit Redis

Rate Limiting schützt Ihre API vor Missbrauch und gewährleistet eine faire Nutzung. Die atomaren Operationen von Redis machen es ideal für die Zählung von Anfragen.

Fixed Window Rate Limiting

Erhöhen Sie einen Zähler für jeden Benutzer pro Zeitfenster. Wenn der Zähler das Limit überschreitet, lehnen Sie die Anfrage ab.

async function isAllowed(userId, limit = 100, windowSec = 60) {
  const key = `rate:${userId}:${Math.floor(Date.now() / 1000 / windowSec)}`;
  const count = await redis.incr(key);
  if (count === 1) await redis.expire(key, windowSec);
  return count