TechnologieProgrammierung

Redis als gemeinsame Cache- und Sessionschicht für viele Anwendungen

netcomputing.de Redaktion26. August 202612 Min. Lesezeit

Zusammenfassung

Mehrere Anwendungen berechnen bei jeder Anfrage dieselben teuren Datenbankabfragen neu und verlieren Sitzungen bei jedem Neustart, weil jede ihren eigenen Prozessspeicher als Cache nutzt. Redis, ein quelloffener In-Memory-Datenspeicher, der seit Mai 2025 wieder unter der AGPLv3-Lizenz steht, dient vielen Anwendungen als gemeinsame Cache- und Sessionschicht. Ein Schlüsselpräfix je Anwendung trennt die Daten in derselben Instanz. Docker-Deployment, Node.js-Anbindung und typische Fallstricke zeigen den Aufbau.

Eine Organisation, die mehrere Anwendungen parallel betreibt, wiederholt in jeder einzelnen dieselbe teure Arbeit. Eine Datenbankaggregation läuft bei jeder Anfrage neu, statt ihr Ergebnis wiederzuverwenden. Eine externe API-Antwort wird bei jedem Aufruf erneut abgeholt, obwohl sie sich seit Minuten nicht geändert hat. Ein gerenderter Seitenausschnitt entsteht bei jedem Seitenaufruf neu, obwohl hundert Besucher in derselben Minute denselben Ausschnitt sehen. Dazu kommt die Sitzungsverwaltung: Jede Anwendung hält die Anmeldedaten ihrer Nutzer im eigenen Prozessspeicher, dem Arbeitsspeicherbereich, den nur dieser eine laufende Prozess kennt. Ein Neustart der Anwendung oder eine zweite Serverinstanz für mehr Last löscht diesen Speicher restlos, und jeder angemeldete Nutzer muss sich neu anmelden.

Redis ist ein In-Memory-Datenspeicher, ein Server, der seinen gesamten Datenbestand im Arbeitsspeicher hält und dadurch Lese- und Schreibzugriffe im Bereich von Mikrosekunden beantwortet. Statt für jede Anwendung eine eigene, isolierte Cache-Logik und eine eigene bezahlte Cache-Instanz zu betreiben, teilen sich mehrere Anwendungen eine gemeinsame Redis-Instanz und trennen ihre Daten über ein eigenes Schlüsselpräfix je Anwendung. Das senkt die Anzahl der zu betreibenden Cache-Server auf einen einzigen und macht Sitzungen unabhängig vom Prozessspeicher der einzelnen Anwendung, weil sie in einem eigenständigen Server liegen, der einen Neustart der Anwendung übersteht. Ob sich das self-hosten überhaupt lohnt, hängt seit 2024 wesentlich von der Lizenz ab, unter der Redis steht, denn das Projekt hat seine Lizenz in den vergangenen zwei Jahren zweimal geändert.

Systemvoraussetzungen

Die folgende Tabelle listet die aktuellen Versionen und Anforderungen für einen gemeinsam genutzten Redis-Aufbau, Stand der Redis-eigenen Dokumentation und des offiziellen GitHub-Repositorys.

KomponenteVersion oder AnforderungZweck
RedisVersion 8.10.1 (Sicherheits-Release vom 17. August 2026, aktuelle stabile Version), seit Redis 8 zusätzlich unter der AGPLv3-Lizenz verfügbarZentraler In-Memory-Datenspeicher für Cache und Sitzungen
DockerOffizielles Image redis:8.10.1 von Docker Hub, Debian- oder Alpine-BasisReproduzierbarer, versionsfixierter Betrieb der Instanz
Persistenter DatenträgerGemountetes Docker-Volume für das Verzeichnis /dataErhält RDB-Snapshot und AOF-Protokoll über Neustarts hinweg
Node.js-Clientnpm-Paket redis (node-redis), laut Redis-Dokumentation der aktuell empfohlene Client für Node.js und JavaScriptVerbindung jeder einzelnen Anwendung zur gemeinsamen Instanz
Schlüsselpräfix je AnwendungEigene, projektweit eindeutige Zeichenkette pro Anwendung, zum Beispiel app-a, app-b, app-cTrennt Cache und Sitzungen mehrerer Anwendungen in derselben Instanz
Quelloffene AlternativeValkey, Version 9.1.1 (21. Juli 2026), BSD-Lizenz, verwaltet von der Linux FoundationFork ohne die Netzwerk-Copyleft-Klausel der AGPLv3

Systemarchitektur

In einem Aufbau mit mehreren Anwendungen bekommt jede Anwendung kein eigenes Redis, sondern nur ihr eigenes Schlüsselpräfix innerhalb derselben Instanz. Eine Anfrage von Anwendung A prüft zuerst, ob unter ihrem Präfix bereits ein passender Schlüssel liegt. Liegt er vor, ist das ein Cache Hit, ein Treffer, und Redis liefert den gespeicherten Wert sofort zurück, ohne dass die eigentliche Datenquelle angefragt wird. Liegt er nicht vor, ist das ein Cache Miss, ein Fehltreffer: Die Anwendung berechnet das Ergebnis selbst oder fragt es bei ihrer Datenbank ab und legt es danach mit einer Ablaufzeit in Redis ab, bevor sie es zurückgibt. Sitzungsdaten laufen über denselben Mechanismus, nur ohne den Umweg über eine zweite Datenquelle: Die Anwendung schreibt die Sitzung direkt unter ihrem Präfix in Redis und liest sie von dort bei jeder folgenden Anfrage, unabhängig davon, welcher Anwendungsprozess oder welche Serverinstanz die Anfrage gerade bedient.

flowchart TD
    A[Anwendung A sendet eine Anfrage] --> D[Schluessel mit Praefix app-a im gemeinsamen Redis]
    B[Anwendung B sendet eine Anfrage] --> E[Schluessel mit Praefix app-b im gemeinsamen Redis]
    C[Anwendung C sendet eine Anfrage] --> F[Schluessel mit Praefix app-c im gemeinsamen Redis]
    D --> G{Schluessel im Speicher vorhanden}
    E --> G
    F --> G
    G -->|Ja, Cache Hit| H[Wert direkt aus dem Speicher liefern]
    G -->|Nein, Cache Miss| I[Datenbankabfrage oder Berechnung ausfuehren]
    I --> J[Ergebnis mit Ablaufzeit im Speicher ablegen]
    J --> H
    D --> K[Sitzungsdaten bleiben nach einem Neustart der Anwendung erhalten]

Die drei Anwendungen A, B und C teilen sich denselben Redis-Prozess, denselben Arbeitsspeicher und dieselbe Netzwerkverbindung, bleiben aber durch ihr jeweiliges Präfix logisch getrennt. Ein Ausfall oder Neustart der Redis-Instanz betrifft zwar alle drei gleichzeitig, ein einzelner Fehler in Anwendung A verändert dagegen nie die Schlüssel von Anwendung B oder C, solange jede Anwendung ausschließlich unter ihrem eigenen Präfix schreibt und liest.

Schritt-für-Schritt-Umsetzung

Redis mit Docker und aktivierter Persistenz starten

Ein einzelner docker run-Befehl reicht, um Redis mit dem offiziellen Image, einem persistenten Datenträger und einer Speichergrenze zu starten. Ohne die Option --appendonly yes bleibt die AOF-Persistenz (Append Only File, ein fortlaufendes Protokoll jedes schreibenden Befehls) deaktiviert, weil appendonly no laut der mit Redis 8.10.1 ausgelieferten Konfigurationsdatei die Voreinstellung ist. Ohne einen gemounteten Datenträger unter /data gehen selbst die automatisch erzeugten RDB-Snapshots, binäre Momentaufnahmen des gesamten Datenbestands, beim Löschen des Containers verloren, weil sie nur im beschreibbaren Containerdateisystem liegen. Drei Schritte reichen für eine erste Instanz.

  1. Ein benanntes Docker-Volume für das Datenverzeichnis anlegen. Ein Volume mit dem Namen redis-data übersteht das Löschen und Neuerstellen des Containers, anders als das Containerdateisystem selbst.
  2. Den Container mit Persistenz- und Speicherflags starten. --appendonly yes aktiviert die AOF-Protokollierung, --maxmemory und --maxmemory-policy setzen die Speichergrenze und die Räumregel dafür.
  3. Die aktive Konfiguration im laufenden Container bestätigen. Ein CONFIG GET über redis-cli zeigt den im laufenden Prozess wirksamen Wert, statt sich auf die Startparameter allein zu verlassen.
docker run -d \
  --name redis-shared \
  -p 6379:6379 \
  -v redis-data:/data \
  redis:8.10.1 \
  redis-server --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru

Die Option --appendonly yes schaltet die AOF-Persistenz ein, sodass jeder schreibende Befehl fortlaufend protokolliert wird und sich beim Start aus dem Protokoll wiederherstellen lässt. Redis legt zusätzlich weiterhin automatisch RDB-Snapshots an, sofern kein leerer save-Wert gesetzt wurde: In der mit Redis ausgelieferten Voreinstellung entsteht ein Snapshot nach einer Stunde bei mindestens einer Änderung, nach fünf Minuten bei mindestens hundert Änderungen und nach einer Minute bei mindestens zehntausend Änderungen. --maxmemory 512mb begrenzt den Arbeitsspeicher, den Redis für den Datenbestand verwendet, und --maxmemory-policy allkeys-lru legt fest, welche Schlüssel Redis entfernt, sobald diese Grenze erreicht ist. Ein Blick in die laufende Konfiguration bestätigt beide Einstellungen.

docker exec redis-shared redis-cli CONFIG GET appendonly
docker exec redis-shared redis-cli CONFIG GET maxmemory-policy

Jede Anwendung über ein eigenes Schlüsselpräfix trennen

Redis bietet für die Trennung mehrerer Datensätze zwei unterschiedliche Mechanismen, und nur einer davon eignet sich für mehrere unabhängige Anwendungen. Der erste Mechanismus sind 16 nummerierte logische Datenbanken, in der Standardeinstellung durchnummeriert von 0 bis 15 und über die Konfigurationsdirektive databases veränderbar; der Befehl SELECT <index> wechselt die aktuell verwendete Datenbank für die jeweilige Verbindung. Die eigene Redis-Dokumentation empfiehlt diesen Weg für den hier beschriebenen Fall ausdrücklich nicht: Nummerierte Datenbanken sollen Schlüssel innerhalb ein und derselben Anwendung trennen, nicht mehrere voneinander unabhängige Anwendungen in einer Instanz. Ein zusätzlicher, praktischer Grund kommt hinzu, sobald eine der Anwendungen wächst: Der Redis-Cluster-Modus, der eine Instanz über mehrere Knoten hinweg skaliert, unterstützt ausschließlich Datenbank 0 und lehnt den SELECT-Befehl für jeden anderen Index ab.

Der zweite Mechanismus, das Schlüsselpräfix, funktioniert dagegen unabhängig davon, ob Redis später als einzelner Prozess oder als Cluster läuft. Jede Anwendung erhält eine eigene, projektweit eindeutige Zeichenkette und stellt sie jedem ihrer Schlüssel voran, getrennt durch einen Doppelpunkt als Konvention.

app-a:session:8f3c1e9b2a
app-a:cache:product-aggregation:4711
app-b:session:2b91af0c7d
app-b:cache:homepage-fragment
app-c:session:7a44d0e912

Alle fünf Schlüssel liegen in derselben Datenbank 0 desselben Redis-Prozesses. Ein Befehl wie KEYS app-b:* oder das für den Produktivbetrieb geeignetere, weil nicht blockierende SCAN mit demselben Muster liefert dabei ausschließlich die Schlüssel von Anwendung B, ohne dass Anwendung A oder C etwas davon mitbekommen.

Sessions und Cache-Aside-Muster mit Node.js anbinden

Node-redis, das npm-Paket redis, ist laut Redis-eigener Dokumentation der aktuell empfohlene Client für Node.js- und JavaScript-Anwendungen. Die Verbindung steht nach dem Aufruf von connect() auf dem zurückgegebenen Client-Objekt, das anschließend von jeder Funktion der Anwendung wiederverwendet wird.

import { createClient } from 'redis';

const APP_PREFIX = 'app-a';

const redisClient = createClient({
  url: process.env.REDIS_URL || 'redis://localhost:6379',
});

redisClient.on('error', (err) => console.error('Redis-Verbindungsfehler', err));

await redisClient.connect();

Eine Sitzung liegt unter dem Präfix der Anwendung als JSON-Zeichenkette mit einer Ablaufzeit (TTL, Time to Live), nach der Redis den Schlüssel automatisch entfernt. Die Option EX beim SET-Befehl setzt diese Ablaufzeit in Sekunden und ersetzt den älteren, funktional identischen Befehl SETEX.

async function saveSession(sessionId, data, ttlSeconds = 1800) {
  await redisClient.set(
    `${APP_PREFIX}:session:${sessionId}`,
    JSON.stringify(data),
    { EX: ttlSeconds },
  );
}

async function getSession(sessionId) {
  const raw = await redisClient.get(`${APP_PREFIX}:session:${sessionId}`);
  return raw ? JSON.parse(raw) : null;
}

Das Cache-Aside-Muster folgt derselben Logik für berechnete Ergebnisse statt für Sitzungen: Die Anwendung fragt zuerst Redis, und nur bei einem Fehltreffer führt sie die teure Datenbankabfrage oder Berechnung aus.

async function getProductAggregation(productId) {
  const cacheKey = `${APP_PREFIX}:cache:product-aggregation:${productId}`;

  const cached = await redisClient.get(cacheKey);
  if (cached) {
    return JSON.parse(cached);
  }

  const fresh = await computeExpensiveAggregation(productId);
  await redisClient.set(cacheKey, JSON.stringify(fresh), { EX: 300 });
  return fresh;
}

Die Ablaufzeit von 300 Sekunden im Beispiel legt fest, wie veraltet das gecachte Ergebnis im schlechtesten Fall sein darf, bevor die nächste Anfrage die Berechnung erneut auslöst. Anwendung B und Anwendung C führen exakt denselben Code mit einem anderen Wert für APP_PREFIX gegen dieselbe Redis-Instanz aus, ohne dass sich ihre Schlüssel jemals überschneiden.

Häufige Fehlerquellen

  • Eine Anwendung löscht mit FLUSHALL oder FLUSHDB die Daten aller anderen mit. FLUSHALL entfernt laut Redis-Dokumentation sämtliche Schlüssel aus allen Datenbanken der Instanz auf einmal, nicht nur die der aufrufenden Anwendung, und FLUSHDB leert zumindest die gesamte aktuell gewählte Datenbank. Beide Befehle lassen sich von jedem verbundenen Client ohne Rückfrage ausführen, sobald keine Berechtigung dagegenspricht. Fix: Über eine Redis-ACL (Access Control List) je Anwendung einen eigenen Benutzer anlegen, dem FLUSHALL und FLUSHDB ausdrücklich verboten sind, statt alle Anwendungen mit dem Standardbenutzer arbeiten zu lassen.
  • Persistenz bleibt auf der Voreinstellung, und ein Neustart löscht alle Sitzungen gleichzeitig. Ohne appendonly yes und ohne gemounteten Datenträger unter /data verliert Redis beim Neustart des Containers seinen gesamten Datenbestand, weil appendonly no die Standardeinstellung ist und ein neuer Container ohne Volume mit einem leeren Dateisystem beginnt. Symptom: Alle angemeldeten Nutzer aller angeschlossenen Anwendungen werden gleichzeitig abgemeldet, sobald die Redis-Instanz aktualisiert oder neu gestartet wird. Fix: --appendonly yes setzen und /data auf ein Docker-Volume oder einen anderen dauerhaften Speicherort mounten, bevor die Instanz produktiv genutzt wird.
  • Zwei Anwendungen wählen Präfixe, die sich beim Mustervergleich überschneiden. Ein Präfix app ohne Trennzeichen matcht bei einem Muster wie app* auch Schlüssel einer später hinzugekommenen Anwendung app2, was Wartungsskripte auf die falschen Schlüssel zugreifen lässt. Fix: Jedes Präfix fest mit einem Doppelpunkt abschließen (app-a:) und neue Präfixe vor der Vergabe gegen eine zentrale Liste bereits vergebener Präfixe prüfen.
  • Kein Grenzwert für maxmemory gesetzt, und der Prozess wächst unkontrolliert. Ohne maxmemory gilt laut Redis-Dokumentation auf 64-Bit-Systemen keine Grenze, sodass der Redis-Prozess so lange wächst, bis der Arbeitsspeicher des Hosts erschöpft ist und das Betriebssystem den Prozess über den Out-of-Memory-Killer beendet. Das reißt dann alle angeschlossenen Anwendungen gleichzeitig aus dem Cache, nicht nur die, die den Speicher zuletzt gefüllt hat. Fix: maxmemory von Anfang an explizit setzen, zusammen mit einer zum Anwendungsfall passenden Richtlinie wie allkeys-lru.
  • SELECT und nummerierte Datenbanken statt Präfixen verwendet, und der Wechsel zu Redis Cluster scheitert. Eine Konfiguration, die Anwendungen über SELECT 1, SELECT 2 und so weiter trennt, läuft auf einer einzelnen Redis-Instanz zunächst unauffällig, bricht aber vollständig, sobald die Instanz später auf einen Redis-Cluster zur horizontalen Skalierung umgestellt wird, weil der Cluster-Modus nur Datenbank 0 unterstützt. Fix: Von Beginn an Schlüsselpräfixe in Datenbank 0 verwenden, auch wenn aktuell nur eine einzelne Instanz ohne Cluster geplant ist.

Häufig gestellte Fragen

Was passiert mit Sitzungsdaten in Redis, wenn der Server ohne aktivierte Persistenz neu startet?

Sitzungsdaten in Redis gehen bei einem Neustart vollständig verloren, wenn weder die AOF-Protokollierung noch RDB-Snapshots aktiv sind, weil Redis den gesamten Datenbestand ausschließlich im Arbeitsspeicher hält. Die Einstellung appendonly no ist laut der mit Redis 8.10.1 ausgelieferten Konfigurationsdatei die Voreinstellung, sodass die AOF-Protokollierung manuell mit appendonly yes eingeschaltet werden muss. Selbst mit den unveränderten Standard-Snapshot-Punkten (nach einer Stunde bei einer Änderung, nach fünf Minuten bei hundert Änderungen, nach einer Minute bei zehntausend Änderungen) gehen alle Schreibvorgänge seit dem letzten Snapshot verloren, sobald der Prozess ohne sauberes Herunterfahren endet.

Ist Redis heute noch eine echte Open-Source-Software, oder gilt wieder eine kommerzielle Lizenz?

Redis ist seit dem 1. Mai 2025 wieder unter einer von der Open Source Initiative anerkannten Lizenz verfügbar, nachdem das Projekt im März 2024 zunächst auf die Server Side Public License und die Redis Source Available License umgestellt hatte und damit den Status als vollständig quelloffene Software verloren hatte. Seit Redis 8 steht der Quellcode zusätzlich unter der AGPLv3 (GNU Affero General Public License Version 3), einer Lizenz mit einer Netzwerk-Copyleft-Klausel: Wer eine modifizierte Version über das Netzwerk als Dienst anbietet, muss auch diese Änderungen offenlegen. Organisationen, die genau diese Klausel vermeiden wollen, weichen häufig auf Valkey aus, den 2024 von der Linux Foundation übernommenen Fork unter der permissiven BSD-Lizenz, der in Version 9.1.1 vom 21. Juli 2026 inzwischen auch bei großen Cloud-Anbietern die Standardauswahl für neu angelegte verwaltete Cache-Dienste ist.

Wie trennt eine gemeinsam genutzte Redis-Instanz die Daten mehrerer Anwendungen voneinander?

Eine gemeinsam genutzte Redis-Instanz trennt die Daten mehrerer Anwendungen in der Praxis über ein eigenes Schlüsselpräfix je Anwendung, etwa app-a: und app-b: vor jedem Schlüsselnamen. Redis besitzt zwar mit den 16 nummerierten logischen Datenbanken (Index 0 bis 15 in der Standardeinstellung) und dem SELECT-Befehl einen eingebauten zweiten Mechanismus, die eigene Dokumentation empfiehlt ihn für diesen Zweck aber ausdrücklich nicht und reserviert ihn für die Trennung von Schlüsseln innerhalb ein und derselben Anwendung. Ein weiterer Grund gegen nummerierte Datenbanken bei mehreren Anwendungen: Der Redis-Cluster-Modus für horizontale Skalierung unterstützt ausschließlich Datenbank 0, sodass eine auf SELECT aufgebaute Trennung bei einem späteren Umstieg auf Cluster-Betrieb vollständig neu aufgebaut werden müsste.

Kann eine Anwendung versehentlich die Cache- und Sitzungsdaten aller anderen Anwendungen in derselben Redis-Instanz löschen?

Eine Anwendung kann mit einem einzigen FLUSHALL-Befehl die Daten aller anderen Anwendungen in derselben Redis-Instanz löschen, weil dieser Befehl laut Redis-Dokumentation sämtliche Schlüssel aus allen Datenbanken auf einmal entfernt und dabei nicht zwischen Anwendungen unterscheidet. Der verwandte Befehl FLUSHDB leert zumindest nur die aktuell gewählte Datenbank, trifft bei einer Trennung über Präfixe in Datenbank 0 aber ebenfalls alle Anwendungen gleichzeitig, weil sie sich dieselbe Datenbank teilen. Beide Befehle lassen sich ohne Rückfrage von jedem Client mit ausreichenden Rechten ausführen; der wirksame Schutz besteht darin, sie über eine Redis-ACL für die Benutzer der einzelnen Anwendungen ausdrücklich zu sperren, statt sich auf Vorsicht beim Schreiben von Wartungsskripten zu verlassen.

Quellen

  1. Redis is now available under the AGPLv3 open source license, Redis, abgerufen am 2026-08-26
  2. Valkey-Projektseite: Version, Lizenz und Traegerschaft der Linux Foundation, Valkey (Linux Foundation), abgerufen am 2026-08-26
  3. Redis-Release 8.10.1 auf GitHub: Versionsnummer und Erscheinungsdatum, Redis-Projekt (GitHub), abgerufen am 2026-08-26
  4. SELECT-Befehl: 16 logische Datenbanken und Empfehlung zu Schluesselpraefixen statt SELECT, Redis-Dokumentation, abgerufen am 2026-08-26
  5. Key eviction: maxmemory-policy-Optionen und ihr Verhalten bei vollem Speicher, Redis-Dokumentation, abgerufen am 2026-08-26
  6. Redis-Konfigurationsuebersicht: Standardwerte wie databases 16 und appendonly no, Redis-Dokumentation, abgerufen am 2026-08-26
  7. Redis-Persistenz: Unterschied zwischen RDB-Snapshots und AOF-Protokoll, Datenverlust ohne Persistenz, Redis-Dokumentation, abgerufen am 2026-08-26
  8. FLUSHALL-Befehl: Loeschung saemtlicher Schluessel aus allen Datenbanken einer Instanz, Redis-Dokumentation, abgerufen am 2026-08-26

Der Content wurde mit Hilfe von KI erstellt, vor allem in der Recherche und Vorformulierung. Prüfung und Abnahme durch unsere Redaktion.