Back openDesk Edu for a sovereign, open-source education — every vote counts.
Vote nowSave products you love by clicking the heart icon.
Produktions-Deployment-Guide für PostgreSQL mit optimierter Konfiguration und Redis mit RDB+AOF-Persistenz, inklusive automatisierter Backups und Point-in-Time-Recovery.
# Connect to a local Redis instance
redis-cli
# Connect to a remote Redis instance
redis-cli -h 192.168.1.100 -p 6379 -a mypassword
# Connect with a specific database (0-15)
redis-cli -n 2
# Run a single command
redis-cli PING
# Pipe commands from stdin
echo -e "SET key value\nGET key" | redis-cli
# Run commands from a file
redis-cli --pipe < commands.txt
# Enable raw output (no formatting)
redis-cli --raw GET key
# Monitor all commands in real time
redis-cli MONITOR
# Latency doctor — analyze slow operations
redis-cli --latency-doctor
# Ping the server
PING # PONG
# Get server information
INFO
INFO server
INFO memory
INFO replication
INFO persistence
INFO clients
# Get the number of keys
DBSIZE
# Flush all keys from the current database
FLUSHDB
# Flush all keys from all databases
FLUSHALL
# Get the Unix timestamp of the last DB save
LASTSAVE
# Change database at runtime
SELECT 1
# Debugging — inspect a key's internal encoding
DEBUG OBJECT mykey
# Slow log — find expensive commands
SLOWLOG GET 10 # Last 10 slow entries
SLOWLOG LEN # Total entries in slow log
SLOWLOG RESET # Clear the slow log
# Client management
CLIENT LIST # List all connected clients
CLIENT KILL <ip>:<port> # Kill a specific client
CLIENT SETNAME myapp # Name the current connection
CLIENT GETNAME # Get the current connection name
CLIENT PAUSE 10000 # Pause all clients for 10s (ms)
Strings sind der grundlegendste Redis-Typ. Ein einzelner Key kann einen String-Wert von bis zu 512 MB speichern. Binärsicher.
# Basic CRUD
SET user:1:name "Alice"
GET user:1:name # "Alice"
DEL user:1:name
# Set with expiration (seconds)
SET session:abc123 "user_data" EX 3600
# Set with expiration (milliseconds)
SET lock:resource "locked" PX 5000
# Set only if key does not exist (NX) or does exist (XX)
SET user:2:name "Bob" NX # Only set if not already present
SET cache:home "html..." XX # Only update if already present
# Get and delete atomically
GETDEL temp:token
# Get and set a new value atomically
GETSET counter:visits 0 # Returns old value, sets new
# Append to a string
APPEND log:entries "line1\n"
APPEND log:entries "line2\n"
# Get substring
GETRANGE log:entries 0 10 # Characters 0 through 10
# Overwrite a substring
SETRANGE greeting 6 "World" # "Hello World" (if greeting was "Hello ")
# Get string length
STRLEN user:1:name
# Increment / decrement
SET page:views 10
INCR page:views # 11 INCRBY page:views 5 # 16 DECR page:views # 15 DECRBY page:views 3 # 12 INCRBYFLOAT balance 0.50 # Floating-Point-Inkrement
MSET user:3:name "Carol" user:3:email "carol@example.com" MGET user:1:name user:2:name user:3:name MGETNX key1 key2 key3 val1 val2 val3 # Setzt mehrere Keys nur, wenn keiner existiert
### Lists
Lists are linked lists of strings. Insertion and deletion at the head or tail are O(1).
```redis
# Elemente hinzufügen (Push)
LPUSH queue:tasks "task1" "task2" "task3" # Push an den Kopf (links)
RPUSH queue:tasks "task4" # Push an das Ende (rechts)
# Elemente entfernen (Pop)
LPOP queue:tasks # Pop vom Kopf — "task3"
RPOP queue:tasks # Pop vom Ende — "task4"
# Pop und Push (Verschieben zwischen Listen)
RPOPLPUSH source:queue dest:queue # Verschiebt das letzte Element atomar
LMOVE source:queue dest:queue LEFT RIGHT # Gleiches mit Richtungssteuerung (Redis 6.2+)
# Blocking Pop (Warten, falls die Liste leer ist)
BLPOP queue:tasks 5 # Blockiert bis zu 5 Sekunden
BRPOP queue:tasks 30 # Blockiert bis zu 30 Sekunden
BLMOVE source:queue dest:queue LEFT RIGHT 30
# Elemente über Index abrufen (0-basiert)
LINDEX queue:tasks 0 # Erstes Element
LINDEX queue:tasks -1 # Letztes Element
# Bereich von Elementen abrufen
LRANGE queue:tasks 0 -1 # Alle Elemente
LRANGE queue:tasks 0 4 # Erste 5 Elemente
# Listenlänge abrufen
LLEN queue:tasks
# Liste auf einen Bereich trimmen
LTRIM recent:logs 0 99 # Behält nur die neuesten 100 Einträge
# Element an Index setzen
LSET queue:tasks 0 "new_task"
# Einfügen vor oder nach einem Pivot-Element
LINSERT mylist BEFORE "pivot" "new_element"
LINSERT mylist AFTER "pivot" "new_element"
# Elemente nach Wert entfernen
LREM mylist -2 "value" # Entfernt die letzten 2 Vorkommen
LREM mylist 2 "value" # Entfernt die ersten 2 Vorkommen
LREM mylist 0 "value" # Entfernt alle Vorkommen
Sets are collections of unique, unsorted strings. O(1) add/remove/membership test.
# Mitglieder hinzufügen / entfernen
SADD tags:article:1 "redis" "database" "nosql" "caching"
SREM tags:article:1 "nosql"
# Mitgliedschaft prüfen
SISMEMBER tags:article:1 "redis" # 1 (true)
SISMEMBER tags:article:1 "mongodb" # 0 (false)
# Alle Mitglieder abrufen
SMEMBERS tags:article:1
# Anzahl der Mitglieder abrufen
SCARD tags:article:1
# Zufälliges Mitglied
SRANDMEMBER tags:article:1 # Gibt ein zufälliges Mitglied zurück (ohne Entfernung)
SRANDMEMBER tags:article:1 3 # Gibt 3 zufällige Mitglieder zurück
# Zufälliges Mitglied entfernen (Pop)
SPOP tags:article:1
# Mitglied zwischen Sets verschieben
SMOVE source:set dest:set "redis"
# Set-Operationen
SADD set:a 1 2 3 4 5
SADD set:b 4 5 6 7 8
SDIFF set:a set:b # Elemente in a, aber nicht in b → {1, 2, 3}
SINTER set:a set:b # Elemente in beiden → {4, 5}
SUNION set:a set:b # Alle Elemente → {1, 2, 3, 4, 5, 6, 7, 8}
# Ergebnisse von Set-Operationen speichern
SDIFFSTORE result:set set:a set:b
SINTERSTORE result:set set:a set:b
SUNIONSTORE result:set set:a set:b
# Durch Set-Mitglieder scannen (cursor-basiert, nicht blockierend)
SSCAN tags:article:1 0 COUNT 100
Sorted sets map unique string members to floating-point scores. Members are ordered by score.
# Mitglieder mit Scores hinzufügen
ZADD leaderboard 100 "player1" 200 "player2" 150 "player3"
# Hinzufügen oder Aktualisieren mit Optionen
ZADD leaderboard NX 300 "player4" # Nur hinzufügen, wenn nicht existent
ZADD leaderboard XX 250 "player2" # Nur aktualisieren, wenn existent
ZADD leaderboard CH 50 "player1" # Gibt Anzahl der geänderten Elemente zurück
ZADD leaderboard GT 120 "player1" # Nur aktualisieren, wenn neuer Score > aktueller Score
# Score abrufen
ZSCORE leaderboard "player1" # 100
# Rang abrufen (0-basiert, aufsteigender Score)
ZRANK leaderboard "player3" # 1
ZREVRANK leaderboard "player3" # 1 (absteigender Score)
# Mitglieder in einem Score-Bereich zählen
ZCOUNT leaderboard 100 200 # 3
# Mitglieder nach Score-Bereich abrufen
ZRANGE leaderboard 0 -1 # Alle Mitglieder (aufsteigend)
ZRANGEBYSCORE leaderboard 100 200 # Mitglieder mit Score 100-200
ZREVRANGE leaderboard 0 -1 # Alle Mitglieder (absteigend)
ZREVRANGEBYSCORE leaderboard 200 100 # Mitglieder mit Score 200-100 (absteigend)
# Inklusive Scores
ZRANGE leaderboard 0 -1 WITHSCORES
ZRANGEBYSCORE leaderboard 100 200 WITHSCORES
# Mitglieder entfernen
ZREM leaderboard "player1"
ZREMRANGEBYRANK leaderboard 0 2 # Die untersten 3 entfernen
ZREMRANGEBYSCORE leaderboard 0 50 # Alle mit Score <= 50 entfernen
# Score eines Mitglieds erhöhen
ZINCRBY leaderboard 10 "player1" # player1 score → 110
# Kardinalität abrufen
ZCARD leaderboard
# Union und Intersection (Scores aggregieren)
ZADD daily:2026-04-19 100 "user1" 200 "user2"
ZADD daily:2026-04-20 150 "user1" 300 "user3"
ZUNIONSTORE weekly:scores 2 daily:2026-04-19 daily:2026-04-20 WEIGHTS 1 1 AGGREGATE SUM
ZINTERSTORE common:scores 2 daily:2026-04-19 daily:2026-04-20
# Lexikographischer Bereich (wenn alle Scores identisch sind)
ZRANGE lex:set [a [z BYLEX
# Durch Mitglieder des Sorted Set scannen
ZSCAN leaderboard 0 COUNT 100
Hashes map string fields to string values. Perfect for representing objects.
# Ein einzelnes Feld setzen
HSET user:1001 name "Alice"
HSET user:1001 email "alice@example.com"
HSET user:1001 age 30
# Mehrere Felder gleichzeitig setzen
HMSET user:1001 name "Alice" email "alice@example.com" age 30
# Nur setzen, wenn das Feld nicht existiert
HSETNX user:1001 role "admin" # Setzt nur, wenn "role" nicht existiert
# Ein einzelnes Feld abrufen
HGET user:1001 name # "Alice"
# Mehrere Felder abrufen
HMGET user:1001 name email age
# Alle Felder und Werte abrufen
HGETALL user:1001
# Felder löschen
HDEL user:1001 age
# Prüfen, ob ein Feld existiert
HEXISTS user:1001 email # 1 (true)
# Anzahl der Felder abrufen
HLEN user:1001
# Alle Feldnamen abrufen
HKEYS user:1001
# Alle Werte abrufen
HVALS user:1001
# Ein numerisches Feld erhöhen
HINCRBY user:1001 login_count 1
HINCRBYFLOAT user:1001 balance 10.50
# Durch Hash-Felder scannen
HSCAN user:1001 0 COUNT 100
Streams are a log data structure with consumer groups. Ideal for event sourcing and messaging.
# Einen Eintrag zu einem Stream hinzufügen
XADD events:user:1001 * name "login" ip "10.0.0.1" timestamp 1745145600000
# Mit spezifischer ID hinzufügen oder automatisch mit * generieren
XADD mystream 0-1 field1 value1 field2 value2
# Stream auf eine maximale Anzahl von Einträgen begrenzen
XADD mystream MAXLEN ~ 10000 * field value # ~ bedeutet approximatives Trimming
# Einträge aus einem Stream lesen
XREAD COUNT 10 STREAMS mystream 0-0 # Alle Einträge
XREAD COUNT 10 STREAMS mystream $ # Nur neue Einträge (blockierend)
# Blockieren, bis neue Einträge eintreffen
XREAD BLOCK 5000 STREAMS mystream $ # Bis zu 5 Sekunden warten
XREAD BLOCK 0 STREAMS mystream $ # Unbegrenzt blockieren
# Einen Bereich von Einträgen per ID lesen
XRANGE mystream - + # Alle Einträge
XRANGE mystream 1672531200000-0 1672617600000-0
# In umgekehrter Reihenfolge lesen
XREVRANGE mystream + -
# Stream-Infos und Länge abrufen
XINFO STREAM mystream
XLEN mystream
# Einen Stream kürzen
XTRIM mystream MAXLEN ~ 1000
# Einträge entfernen
XDEL mystream 1672531200000-0
# Consumer-Gruppen
XGROUP CREATE mystream mygroup $ MKSTREAM # Gruppe erstellen, Start bei neuen Einträgen
XGROUP CREATE mystream mygroup 0-0 MKSTREAM # Gruppe erstellen, vom Anfang an lesen
XGROUP DESTROY mystream mygroup # Gruppe löschen
# Als Consumer in einer Gruppe lesen
XREADGROUP GROUP mygroup consumer1 COUNT 5 STREAMS mystream >
# Nachrichten bestätigen
XACK mystream mygroup 1672531200000-0 1672531200000-1
# Ausstehende Nachrichten beanspruchen (für abgestürzte Consumer)
XCLAIM mystream mygroup consumer2 3600000 1672531200000-0 1672531200000-1
# Ausstehende Einträge anzeigen
XPENDING mystream mygroup
XPENDING mystream mygroup - + 10 # Detaillierte Infos zu ausstehenden Einträgen
# Consumer-Gruppen eines Streams auflisten
XINFO GROUPS mystream
# Consumer in einer Gruppe auflisten
XINFO CONSUMERS mystream mygroup
# Autoclaim — ausstehende Nachrichten beanspruchen und zurückgeben
XAUTOCLAIM mystream mygroup consumer2 3600000 0-0 COUNT 10
Bitmaps are string-based bit arrays. Perfect for flags, presence sets, and analytics.
# Ein Bit setzen (Offset ist 0-basiert)
SETBIT user:1001:logins 0 1 # Tag 0: eingeloggt
SETBIT user:1001:logins 1 1 # Tag 1: eingeloggt
SETBIT user:1001:logins 2 0 # Tag 2: nicht eingeloggt
# Ein Bit abrufen
GETBIT user:1001:logins 0 # 1
# gesetzte Bits zählen
BITCOUNT user:1001:logins # Gesamtzahl der eingeloggten Tage
BITCOUNT user:1001:logins 0 1 # Bits im Byte-Bereich 0-1 zählen
# Bitweise Operationen (Ergebnis in destkey speichern)
SETBIT flags:a 0 1
SETBIT flags:a 3 1
SETBIT flags:b 1 1
SETBIT flags:b 3 1
BITOP AND result:flags flags:a flags:b # {0,1,0,1} AND {0,1,0,1} → {0,1,0,1}
BITOP OR result:flags flags:a flags:b
BITOP XOR result:flags flags:a flags:b
BITOP NOT result:flags flags:a
# Erstes gesetztes Bit finden
BITPOS user:1001:logins 1 # Erster Tag mit Login
BITPOS user:1001:logins 0 # Erster Tag ohne Login
# Praxisbeispiel: Tracking täglich aktiver Nutzer für ein bestimmtes Datum
SETBIT active:2026-04-20 <user_id> 1
BITCOUNT active:2026-04-20 # Gesamtzahl der aktiven Nutzer an diesem Tag
HyperLogLog provides probabilistic cardinality estimation with ~0.81% standard error using minimal memory (12 KB per key).
# Elemente hinzufügen
PFADD unique:visitors:page:home "user1" "user2" "user3" "user1"
# Geschätzte Kardinalität abrufen
PFCOUNT unique:visitors:page:home # 3 (geschätzt)
# Mehrere HLLs zusammenführen
PFADD unique:visitors:day1 "user1" "user2"
PFADD unique:visitors:day2 "user2" "user3"
PFMERGE unique:visitors:combined unique:visitors:day1 unique:visitors:day2
PFCOUNT unique:visitors:combined # ~3
# Praxisbeispiel: Monatliche Unique Page Views
PFADD uv:2026-04-20 "user1" "user2" "user3"
PFADD uv:2026-04-21 "user2" "user4" "user5"
PFMERGE uv:2026-04 uv:2026-04-20 uv:2026-04-21
PFCOUNT uv:2026-04 # ~5 Unique User
# Ablaufzeit setzen (Sekunden)
EXPIRE session:abc 3600 # Läuft in 1 Stunde ab
EXPIREAT session:abc 1745232000 # Läuft bei Unix-Timestamp ab
# Ablaufzeit setzen (Millisekunden)
PEXPIRE session:abc 3600000
PEXPIREAT session:abc 1745232000000
# Verbleibende Lebensdauer abrufen
TTL session:abc # Verbleibende Sekunden (-1 = kein Ablauf, -2 = Key nicht vorhanden)
PTTL session:abc # Verbleibende Millisekunden
# Key dauerhaft speichern (Ablaufzeit entfernen)
PERSIST session:abc
# Setzen mit integrierter Ablaufzeit
SET cache:product:42 "data" EX 300 # Ablauf in 5 Minuten
SET lock:order:99 "held" PX 10000 # Ablauf in 10 Sekunden
# KEYS pattern (WARNUNG: blockiert den Server, nur in der Entwicklung verwenden)
KEYS user:* # Alle Keys, die mit "user:" beginnen
KEYS session:???:* # 3-stellige ID nach "session:"
# SCAN — cursor-basierte, nicht-blockierende Alternative
SCAN 0 MATCH user:* COUNT 100 # Erster Batch
SCAN 34 MATCH user:* COUNT 100 # Nächster Batch (Cursor = 34)
SCAN 0 MATCH session:* COUNT 100 COUNT 1000 # Größere Batches
# Typ-Prüfung
TYPE mykey # string, list, set, zset, hash, stream, etc.
# Existenz prüfen
EXISTS mykey # 1 wenn vorhanden, 0 wenn nicht
EXISTS key1 key2 key3 # Anzahl der existierenden Keys
# Umbenennen
RENAME oldkey newkey # Überschreibt newkey, falls dieser existiert
RENAMENX oldkey newkey # Nur umbenennen, wenn newkey nicht existiert
# Key kopieren (Redis 6.2+)
COPY sourcekey destkey
# Dump und Restore (binäre Serialisierung)
DUMP mykey
RESTORE newkey 0 "<serialized-data>"
# Key serialisieren, um die Kodierung zu sehen
DEBUG OBJECT mykey
# Keys sortieren (funktioniert bei lists, sets, sorted sets)
SORT mylist ALPHA
SORT mylist BY weight:* DESC LIMIT 0 10
SORT mylist BY weight:* DESC GET object:*->name
Redis transactions group multiple commands into a single atomic operation. All commands are queued and executed sequentially.
# Einfache Transaktion
MULTI
SET user:1:balance 1000
DECRBY user:1:balance 200
INCRBY user:2:balance 200
EXEC
# Transaktion verwerfen
MULTI
SET key1 value1
DISCARD # Bricht die Transaktion ab
# Optimistisches Locking mit WATCH
WATCH account:1001 # Key auf Änderungen überwachen
balance = GET account:1001 # Aktuellen Kontostand lesen
MULTI
SET account:1001 <new_balance>
EXEC # Erfolgreich nur, wenn account:1001 nicht geändert wurde
# UNWATCH — alle überwachten Keys abbrechen
UNWATCH
# Fehler innerhalb einer Transaktion: Syntaxfehler führen dazu, dass EXEC komplett fehlschlägt,
# aber Typfehler (z. B. INCR auf einem String) werden stillschweigend übersprungen.
MULTI
SET foo bar
INCR foo # Typfehler: foo ist ein String
SET baz qux
EXEC # foo="bar", INCR wird übersprungen, baz="qux"
# Redis unterstützt KEIN Rollback — behandeln Sie Fehler in Ihrer Anwendung.
Redis publish/subscribe enables real-time messaging between clients.
# Kanälen abonnieren
SUBSCRIBE channel:notifications
SUBSCRIBE channel:notifications channel:alerts channel:logs
# Einem Pattern abonnieren
PSUBSCRIBE channel:user:* # Matcht channel:user:1001, etc.
# Nachricht veröffentlichen
PUBLISH channel:notifications "Order #1234 has been shipped"
# Deabonnieren
UNSUBSCRIBE channel:notifications
PUNSUBSCRIBE channel:user:*
# Aktive Kanäle auflisten
PUBSUB CHANNELS # Alle aktiven Kanäle
PUBSUB CHANNELS channel:user:* # Kanäle, die dem Pattern entsprechen
PUBSUB NUMSUB channel:notifications # Anzahl der Abonnenten
PUBSUB NUMPAT # Anzahl der Pattern-Abonnements
Lua-Skripte werden atomar auf dem Server ausgeführt, wodurch sichergestellt wird, dass während der Ausführung keine anderen Befehle ausgeführt werden.
# EVAL — run a Lua script
EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 mykey myvalue
# EVALSHA — run by SHA1 digest (cached on server)
SCRIPT LOAD "return redis.call('SET', KEYS[1], ARGV[1])"
# Returns: sha1_digest
EVALSHA sha1_digest 1 mykey myvalue
# Script management
SCRIPT EXISTS <sha1> <sha2> # Check if scripts are cached
SCRIPT FLUSH # Remove all cached scripts
SCRIPT KILL # Kill a currently running script
# Example: atomic rate limiter
EVAL "
local current = redis.call('GET', KEYS[1])
if current and tonumber(current) >= tonumber(ARGV[1]) then
return 0
end
redis.call('INCR', KEYS[1])
redis.call('EXPIRE', KEYS[1], ARGV[2])
return 1
" 1 rate:user:1001 10 60
redis.call() für Befehle und redis.pcall() für Aufrufe, die keine Exceptions auslösen.redis.replicate_commands() für Schreibskripte.SCRIPT LOAD + EVALSHA, um zu vermeiden, dass der Skriptkörper bei jedem Aufruf übertragen wird.Point-in-Time-Snapshots des Datensatzes, die als binäre .rdb-Dateien gespeichert werden.
# redis.conf — RDB settings
save 900 1 # Save after 900 seconds if at least 1 key changed
save 300 10 # Save after 300 seconds if at least 10 keys changed
save 60 10000 # Save after 60 seconds if at least 10000 keys changed
save "" # Disable RDB saves entirely
rdbcompression yes # Compress RDB files with LZF
rdbchecksum yes # Append CRC64 checksum
dbfilename dump.rdb # RDB filename
dir /var/lib/redis # RDB directory
# Manual save
redis-cli BGSAVE # Fork a child process to save (non-blocking)
redis-cli SAVE # Block until save completes (avoid in production)
Protokolliert jede Schreiboperation sequenziell. Langlebiger als RDB, führt jedoch zu größeren Dateien.
# redis.conf — AOF settings
appendonly yes # Enable AOF
appendfilename "appendonly.aof" # AOF filename
appendfsync everysec # Sync once per second (recommended)
# appendfsync always # Sync every write (safest, slowest)
# appendfsync no # Let OS decide (fastest, least safe)
auto-aof-rewrite-percentage 100 # Rewrite when AOF is 100% larger than last rewrite
auto-aof-rewrite-min-size 64mb # Minimum size to trigger rewrite
no-appendfsync-on-rewrite no # Continue fsync during rewrite
# Manual rewrite
redis-cli BGREWRITEAOF
| Feature | RDB | AOF |
|---|---|---|
| Haltbarkeit | Point-in-Time-Snapshots | Jeder Schreibvorgang wird protokolliert |
| Dateigröße | Kompaktes Binärformat | Größer, textbasiert |
| Wiederherstellungsgeschwindigkeit | Schnell | Langsamer |
| Schreibperformance | Geringere Auswirkungen auf Schreibvorgänge | Kann Schreiblatenz beeinflussen |
| Datenverlustfenster | Minuten (basierend auf Speicherregeln) | ~1 Sekunde (everysec) |
| Bestens geeignet für | Backups, Disaster Recovery | Produktions-Haltbarkeit |
# Use both RDB and AOF together
# RDB for base file + AOF incremental changes
aof-use-rdb-preamble yes
Die Redis-Replikation erstellt eine oder mehrere Read-Replicas eines Master-Nodes.
# Auf der Replica — Verbindung zu einem Master herstellen
redis-cli REPLICAOF 192.168.1.100 6379
# Auf einer Replica — zum Master befördern
redis-cli REPLICAOF NO ONE
# Replikationsstatus prüfen
redis-cli INFO replication
# Master-Passwort konfigurieren (falls erforderlich)
masterauth <password>
# Replica schreibgeschützt (Standard: yes)
replica-read-only yes
replica-serve-stale-data yes repl-backlog-size 1mb
### Replication Architecture
```bash
# redis.conf auf dem Master
bind 0.0.0.0
protected-mode no
requirepass your_strong_password
masterauth your_strong_password
# redis.conf auf der Replica
replicaof <master_ip> <master_port>
masterauth your_strong_password
replica-read-only yes
# Partielle Resynchronisation (PSYNC)
# Replicas führen einen Replikations-Backlog, um Wiederverbindungen zu handhaben
repl-backlog-size 10mb
repl-backlog-ttl 3600
Redis Sentinel provides automatic failover, monitoring, and notification for Redis masters.
# sentinel.conf (minimale viable Konfiguration)
sentinel monitor mymaster 127.0.0.1 6379 2 # Name, Host, Port, Quorum
sentinel down-after-milliseconds mymaster 5000 # Master nach 5s als down markieren
sentinel failover-timeout mymaster 60000 # Failover-Timeout: 60s
sentinel parallel-syncs mymaster 1 # Eine Replica gleichzeitig replizieren
# Sentinel starten
redis-sentinel /path/to/sentinel.conf
# Sentinel-Befehle
redis-cli -p 26379 SENTINEL masters # Überwachte Master auflisten
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster # Aktueller Master
redis-cli -p 26379 SENTINEL replicas mymaster # Replicas auflisten
redis-cli -p 26379 SENTINEL ckquorum mymaster # Quorum prüfen
redis-cli -p 26379 SENTINEL failover mymaster # Failover erzwingen
# Anwendungen sollten sich über Sentinel verbinden, um den Master zu finden
# Sentinel gibt die IP und den Port des aktuellen Masters dynamisch zurück
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
# 1) "192.168.1.100"
# 2) "6379"
Redis Cluster shards data automatically across multiple nodes (minimum 3 masters + 3 replicas for production).
# Cluster aus Nodes erstellen
redis-cli --cluster create \
192.168.1.101:6379 \
192.168.1.102:6379 \
192.168.1.103:6379 \
192.168.1.104:6379 \
192.168.1.105:6379 \
192.168.1.106:6379 \
--cluster-replicas 1
# Neuen Node hinzufügen
redis-cli --cluster add-node 192.168.1.107:6379 192.168.1.101:6379
# Node als Replica hinzufügen
redis-cli --cluster add-node \
192.168.1.108:6379 192.168.1.101:6379 \
--cluster-slave
# Slots über Nodes rebalancen
redis-cli --cluster rebalance 192.168.1.101:6379
# Node entfernen
redis-cli --cluster del-node 192.168.1.107:6379 <node-id>
# Cluster-Status prüfen
redis-cli --cluster check 192.168.1.101:6379
# Cluster-Infos
redis-cli CLUSTER INFO
redis-cli CLUSTER NODES
redis-cli CLUSTER SLOTS
redis-cli CLUSTER KEYSLOT "mykey" # Welcher Slot für einen Key gehasht wird
# redis.conf für den Cluster-Modus
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 192.168.1.101
cluster-announce-port 6379
# Hash Tags — verwandte Keys in denselben Slot zwingen
# Keys innerhalb von {} nutzen nur den Inhalt der Klammern für das Hashing
SET {user:1001}:name "Alice"
SET {user:1001}:email "alice@example.com"
SET {user:1001}:age 30
# Alle drei Keys werden in denselben Slot gehasht → können in Multi-Key-Operationen verwendet werden
{...}, um verwandte Keys zu gruppieren).redis.call() aufgerufenen Keys deklarieren, damit Redis verifizieren kann, dass sie sich im selben Slot befinden.# Memory info
redis-cli INFO memory
# Max memory policy
maxmemory 2gb
maxmemory-policy allkeys-lru # Evict least recently used keys
# maxmemory-policy volatile-lru # Evict LRU among keys with TTL set
# maxmemory-policy allkeys-lfu # Evict least frequently used keys (Redis 4.0+)
# maxmemory-policy volatile-lfu # Evict LFU among keys with TTL set
# maxmemory-policy allkeys-random # Evict random keys
# maxmemory-policy volatile-random # Evict random keys with TTL set
# maxmemory-policy volatile-ttl # Evict keys with shortest TTL first
# maxmemory-policy noeviction # Return errors when memory limit reached
# Sampled LRU — Redis uses an approximation of LRU for efficiency
# It samples N keys and evicts the least recently used among the sample
maxmemory-samples 5 # Default: 5 (higher = more accurate, slower)
# LFU tuning (Redis 4.0+)
lfu-log-factor 10 # Counter logarithmic factor (higher = slower decay)
lfu-decay-time 1 # Decay time in minutes
# Inspect memory usage of a key
redis-cli MEMORY USAGE mykey
# Memory allocator stats
redis-cli MEMORY STATS
# Memory doctor — get optimization advice
redis-cli MEMORY DOCTOR
# Purge expired keys (usually automatic)
redis-cli --scan | xargs -L 1000 redis-cli UNLINK
# Use hashes to save memory for related fields
# Small hashes (< hash-max-ziplist-entries) are encoded as ziplists
# 100 hashes with 1 field each → ~100 keys (wasteful)
# vs 1 hash with 100 fields → compact ziplist encoding
# Configure encoding thresholds
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
# Connection pool settings (in redis.conf)
maxclients 10000 # Max simultaneous clients
timeout 300 # Close idle clients after 300 seconds
tcp-keepalive 60 # TCP keepalive interval
# TLS (Redis 6.0+)
tls-port 6379
tls-cert-file /path/to/redis.crt
tls-key-file /path/to/redis.key
tls-ca-cert-file /path/to/ca.crt
tls-auth-clients optional
redis-cli --tls --cert ./client.crt --key ./client.key --cacert ./ca.crt
# Unix socket (faster than TCP for local connections)
unixsocket /var/run/redis/redis.sock
unixsocketperm 700
redis-cli -s /var/run/redis/redis.sock
# Authentication
requirepass your_strong_password
redis-cli -a your_strong_password # Connect with password
CONFIG SET requirepass "newpass" # Change password at runtime
CONFIG GET requirepass # Retrieve password (shows as asterisks in logs)
# ACL (Access Control Lists — Redis 6.0+)
ACL SETUSER developer on +@all -@dangerous >dev_password ~*
ACL SETUSER readonly on +@read ~* >readonly_pass
ACL SETUSER appuser on +@all -DEBUG -CONFIG -SHUTDOWN +SET +GET +DEL ~app:*
ACL LIST # List all ACL rules
ACL WHOAMI # Show current user
ACL CAT # List all command categories
ACL GENPASS # Generate a random password
ACL DELUSER developer # Delete a user
# Fixed-window rate limiter unter Verwendung von INCR + EXPIRE
# Erlaube 10 Anfragen pro Minute pro Benutzer
# Lua-Skript für Atomarität
EVAL "
local key = KEYS[1]
local limit = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local current = redis.call('INCR', key)
if current == 1 then
redis.call('EXPIRE', key, window)
end
if current > limit then
return 0
end
return current
" 1 rate:user:1001 10 60
ZADD rate:ip:10.0.0.1 <timestamp_ms> <unique_id> ZREMRANGEBYSCORE rate:ip:10.0.0.1 -inf <timestamp_ms - 3600000> ZCARD rate:ip:10.0.0.1
### Caching
```redis
# Cache-aside Pattern (anwendungsseitig)
# 1. Zuerst Cache prüfen
GET cache:user:1001
# 2. Bei Miss aus Datenbank abrufen, dann:
SET cache:user:1001 "<json_data>" EX 300
# Cache mit Refresh-ahead (Erneuerung vor Ablauf)
GET cache:product:42
# Wenn TTL < 60 Sekunden, asynchronen Refresh auslösen
TTL cache:product:42
# Cache-Invalidierung beim Schreiben
SET cache:user:1001 "<new_data>" EX 300 # Write-through
# Oder bei Update:
DEL cache:user:1001 # Invalidate
# Distributed Lock mit SET NX
SET lock:order:99 "unique_token" NX PX 10000
# Gibt OK zurück, wenn Lock erworben wurde, nil wenn bereits belegt
# Freigabe mit einem Lua-Skript (Besitz prüfen):
EVAL "
if redis.call('GET', KEYS[1]) == ARGV[1] then
return redis.call('DEL', KEYS[1])
else
return 0
end
" 1 lock:order:99 unique_token
# Score eines Spielers hinzufügen oder aktualisieren
ZADD leaderboard:global 1500 "player:1001"
ZINCRBY leaderboard:global 50 "player:1001" # +50 Punkte
# Top N Spieler (höchste Scores zuerst)
ZREVRANGE leaderboard:global 0 9 WITHSCORES # Top 10
ZREVRANGE leaderboard:global 0 99 WITHSCORES # Top 100
# Rang eines Spielers abrufen
ZREVRANK leaderboard:global "player:1001" # 0-basierter Rang
ZSCORE leaderboard:global "player:1001" # 1550
# Spieler nahe eines bestimmten Rangs (für Pagination)
# Score des Spielers an der Grenze abrufen, dann:
ZREVRANGEBYSCORE leaderboard:global 1550 1400 WITHSCORES
# Top N Spieler innerhalb eines spezifischen Bereichs
ZREVRANGEBYSCORE leaderboard:global 2000 1500 WITHSCORES LIMIT 0 10
# Spieler entfernen
ZREM leaderboard:global "player:1001"
# Einfache FIFO-Queue mit Lists
RPUSH queue:emails "send_welcome user@example.com"
RPUSH queue:emails "send_invoice order:99"
BLPOP queue:emails 30 # Worker: blockiert bis zu 30s für den nächsten Job
# Zuverlässige Queue mit Sorted Sets (Priority Queue)
ZADD queue:jobs <priority> <job_id>
# Worker: Job mit der höchsten Priorität beanspruchen
ZPOPMIN queue:jobs # Pop niedrigster Score (höchste Priorität, falls niedriger = höher)
# Delayed Queue (verzögerte Queue)
ZADD queue:delayed <execute_at_timestamp> <job_id>
# Worker: Pollen nach fälligen Jobs
ZRANGEBYSCORE queue:delayed -inf <current_timestamp> LIMIT 0 10
ZREM queue:delayed <job_id>
# Zuverlässige Verarbeitung mit Streams (empfohlen für Produktion)
XADD stream:orders * event "created" order_id "1234" customer "1001"
XREADGROUP GROUP workers worker-1 COUNT 1 BLOCK 5000 STREAMS stream:orders >
# Job verarbeiten...
XACK stream:orders workers <message_id>
# Page-View-Counter
INCR page:views:/about
GET page:views:/about
# Täglicher Counter mit automatischer Ablaufzeit
INCR stats:pageviews:2026-04-20
EXPIRE stats:pageviews:2026-04-20 172800 # Ablauf in 2 Tagen
# Aktions-Counter pro Benutzer
HINCRBY user:1001:stats logins 1
HINCRBY user:1001:stats purchases 1
HGET user:1001:stats logins
# Runtime-Konfiguration
CONFIG GET maxmemory # Konfigurationswert abrufen
CONFIG GET "*" # Alle Konfigurationen abrufen
CONFIG SET maxmemory 2gb # Konfigurationswert zur Laufzeit setzen
CONFIG REWRITE # Runtime-Konfiguration in redis.conf persistieren
# Gängige Konfiguration
bind 127.0.0.1 # Auf spezifischen Interfaces lauschen
port 6379 # Listen port
daemonize yes # Run as daemon
pidfile /var/run/redis/redis-server.pid
logfile /var/log/redis/redis.log
loglevel notice # debug, verbose, notice, warning
databases 16 # Number of databases (default: 16)
# Slow log
slowlog-log-slower-than 10000 # Log commands slower than 10ms
slowlog-max-len 128 # Keep last 128 slow entries
object-type:id:field (z. B. user:1001:profile).SCAN anstelle von KEYS in der Produktion — KEYS blockiert den Server.appendonly yes für die Persistenz in der Produktion oder nutzen Sie eine gemischte Persistenz.UNLINK anstelle von DEL für große Keys — dies löscht asynchron in einem Hintergrund-Thread.{...} im Cluster-Modus, um verwandte Keys im selben Slot zu halten.maxmemory-policy auf allkeys-lru oder volatile-lru, um Speicherengpässe (Memory Pressure) elegant zu handhaben.requirepass für eine feingranulare Zugriffskontrolle.INFO, SLOWLOG und MEMORY DOCTOR regelmäßig in der Produktion.In-Memory Data Structure Store Reference