Redis und der daraus hervorgegangene Ableger Valkey machen dasselbe: Sie halten Schlüssel-Wert-Paare im Arbeitsspeicher. Für Sitzungen, Warteschlangen, Sperren und Zwischenspeicher ist das die richtige Antwort, vorausgesetzt, zwei Einstellungen stimmen und der Port ist zu.
Wofür und wofür nicht#
| Passt | Passt nicht |
|---|---|
| Sitzungen einer Webanwendung | dauerhafte Geschäftsdaten |
| Zwischenspeicher teurer Abfragen | alles, was eine Abfrage über mehrere Felder braucht |
| Warteschlangen und Aufträge | Daten, deren Verlust weh tut |
| Sperren zwischen Prozessen | große Dateien |
Der Grund für die rechte Spalte: Alles liegt im Arbeitsspeicher. Was nicht hineinpasst, wird verdrängt und was beim Absturz noch nicht auf der Platte war, ist weg. Das ist kein Mangel, sondern der Zweck. Wer Dauerhaftigkeit braucht, nimmt PostgreSQL oder MariaDB.
Aufsetzen#
services:
cache:
image: valkey/valkey:8-alpine
restart: unless-stopped
command: >
valkey-server
--maxmemory 512mb
--maxmemory-policy allkeys-lru
--save ""
--appendonly no
--requirepass ${CACHE_PASSWORT:?fehlt}
ports:
- "127.0.0.1:6379:6379"
volumes:
- cache-daten:/data
volumes: { cache-daten: }
Das Passwort kommt aus einer .env-Datei mit Rechten 600, die Begründung und die Stufen darüber stehen in Passwörter in Containern.
Ein Schlüssel-Wert-Speicher ohne Passwort im Internet ist eines der am schnellsten ausgenutzten Ziele überhaupt: Er lässt sich nicht nur auslesen und leeren, sondern über seine Konfigurationsbefehle auch dazu bringen, Dateien auf die Platte zu schreiben, was in der Vergangenheit reihenweise zu übernommenen Servern geführt hat. 127.0.0.1: vor dem Port und ein Passwort sind hier kein Feinschliff, sondern die Grundeinstellung. Und Docker greift an ufw vorbei, siehe Container-Netze verstehen.
# Gegenprobe von außen — muss ins Leere laufen:
nc -zv <server-ip> 6379
# und lokal:
ss -tlnp | grep 6379 # erwartet: 127.0.0.1
Die zwei Einstellungen, die zählen#
maxmemory und die Verdrängung#
Ohne Obergrenze wächst der Dienst, bis der Kernel einen Prozess beendet und das ist selten der richtige.
--maxmemory 512mb
--maxmemory-policy allkeys-lru
| Regel | Verhalten | Wann |
|---|---|---|
noeviction | schreibt nicht mehr, meldet Fehler | wenn nichts verloren gehen darf (Warteschlange) |
allkeys-lru | verdrängt die am längsten ungenutzten | reiner Zwischenspeicher |
volatile-lru | verdrängt nur Schlüssel mit Ablaufzeit | gemischte Nutzung |
Die Standardeinstellung ist noeviction, für einen Cache also die falsche: Er läuft voll und lehnt neue Einträge ab, statt alte wegzuwerfen.
Persistenz: an oder aus#
--save "" # keine Momentaufnahmen
--appendonly no # kein Schreibprotokoll
Für einen reinen Zwischenspeicher ist das richtig: Nach einem Neustart ist er leer und füllt sich wieder. Wer den Dienst für Sitzungen benutzt, sollte wissen, was das heißt, alle Anmeldungen sind nach dem Neustart weg. Wer das nicht will, schaltet appendonly yes ein und kauft dafür Schreiblast und eine Datei, die wachsen kann.
Im Betrieb nachsehen#
docker compose exec cache valkey-cli -a "$CACHE_PASSWORT" INFO memory | head -12
docker compose exec cache valkey-cli -a "$CACHE_PASSWORT" INFO stats | grep -E "keyspace_hits|keyspace_misses|evicted_keys"
Drei Zahlen daraus:
- Trefferquote aus
keyspace_hitsundkeyspace_misses. Unter etwa 80 % lohnt der Blick, ob überhaupt das Richtige zwischengespeichert wird. evicted_keyssteigt stetig → die Obergrenze ist zu niedrig für den Bestand.used_memorynahemaxmemoryist normal, nicht alarmierend, so soll ein Cache arbeiten.
# Was liegt eigentlich drin? (KEYS niemals auf einem belasteten System)
docker compose exec cache valkey-cli -a "$CACHE_PASSWORT" --scan --pattern 'sess:*' | head
KEYS * blockiert den Dienst, solange es läuft. --scan tut das nicht, der Unterschied fällt erst auf einem vollen System auf, und dann unangenehm.
Redis oder Valkey?#
Beide sprechen dasselbe Protokoll; bestehende Anwendungen merken den Unterschied nicht. Valkey entstand als Abspaltung, nachdem Redis seine Lizenz geändert hatte, und wird von einer Stiftung getragen. Für einen neuen Aufbau ohne Lizenzfragen ist Valkey die unkompliziertere Wahl, die Befehle in diesem Beitrag gelten für beide.
Häufige Fragen#
Wie groß sollte der Cache sein?#
So groß, dass die häufig gelesenen Daten hineinpassen, nicht größer. evicted_keys und die Trefferquote sagen dir, ob du richtig liegst.
Brauche ich ihn überhaupt?#
Erst, wenn eine Messung zeigt, dass dieselben teuren Abfragen wiederholt laufen. Ein Cache vor einem Problem, das nicht existiert, fügt nur eine weitere Sache hinzu, die ausfallen kann.
Was passiert, wenn er ausfällt?#
Das entscheidet die Anwendung. Gut gebaute Anwendungen rechnen dann eben langsam weiter; schlecht gebaute werfen Fehler. Das gehört einmal ausprobiert, bevor es nachts von allein passiert.
Kann ich ihn für mehrere Anwendungen benutzen?#
Ja, mit getrennten Datenbanknummern oder Schlüssel-Präfixen. Sauberer sind getrennte Instanzen, sie können unterschiedliche Verdrängungsregeln haben, und ein Leeren trifft nicht beide.
Und Cluster?#
Für einen VPS praktisch nie nötig. Ein einzelner Dienst mit passender Obergrenze trägt sehr viel, bevor Aufteilung ein Thema wird.
Kurz gesagt#
maxmemoryund eine passende Verdrängungsregel, der Standardnoevictionist für Caches falsch.127.0.0.1:vor den Port, Passwort setzen. Dieser Dienst ist ein bevorzugtes Ziel.- Persistenz bewusst wählen: aus für Caches, an für Sitzungen, mit den Folgen.
- Im Betrieb auf Trefferquote und
evicted_keyssehen. --scanstattKEYS *.
Geschrieben aus dem laufenden Betrieb: MRMedia betreibt eigene Proxmox- Hosts, einen Backup-Server und Kundendienste in der EU. Fehler in einer Anleitung sind Fehler im eigenen Betrieb. Korrekturen bitte über Discord.