Redis ist ein schneller In-Memory Key-Value-Store. Er wird für Caching, Sessions, Queues und Echtzeit-Anwendungen eingesetzt.

Vorteile von Redis

Anwendungsfälle

- Session-Speicher
- Cache für Datenbank-Queries
- Rate Limiting
- Message Queue
- Pub/Sub Messaging
- Leaderboards
- Echtzeit-Analytik

Performance

- Single-threaded (kein Locking)
- Daten im RAM (~100.000 ops/sec)
- Persistenz optional
- Replikation und Clustering

Installation

Debian/Ubuntu

apt update
apt install redis-server

CentOS/RHEL

dnf install redis

Docker

docker run -d \
  --name redis \
  -p 6379:6379 \
  -v redis-data:/data \
  redis:7-alpine

Service starten

systemctl enable --now redis-server
# oder
systemctl enable --now redis

Grundkonfiguration

redis.conf

# /etc/redis/redis.conf

# Netzwerk
bind 127.0.0.1
port 6379
protected-mode yes

# Speicher
maxmemory 256mb
maxmemory-policy allkeys-lru

# Persistenz
save 900 1
save 300 10
save 60 10000
appendonly yes

# Sicherheit
requirepass MySecretPassword

Speicher-Limits

# Maximaler Speicher
maxmemory 1gb

# Eviction Policy (wenn voll)
maxmemory-policy allkeys-lru   # LRU für alle Keys
maxmemory-policy volatile-lru  # LRU nur für Keys mit TTL
maxmemory-policy noeviction    # Fehler bei vollem Speicher

Redis CLI

Verbinden

# Lokal
redis-cli

# Remote
redis-cli -h hostname -p 6379 -a password

# Mit Datenbank
redis-cli -n 1

Grundbefehle

# String setzen/lesen
SET name "Max"
GET name

# Mit TTL (Sekunden)
SETEX session:123 3600 "data"

# Existiert?
EXISTS name

# Löschen
DEL name

# TTL prüfen
TTL session:123

# Alle Keys
KEYS *
KEYS user:*

Datentypen

Strings

# Setzen
SET counter 10

# Inkrementieren
INCR counter       # 11
INCRBY counter 5   # 16
DECR counter       # 15

# Append
APPEND name " Mustermann"

# Mehrere Keys
MSET key1 "val1" key2 "val2"
MGET key1 key2

Lists

# Push
LPUSH queue "item1"          # Links einfügen
RPUSH queue "item2"          # Rechts einfügen

# Pop
LPOP queue                   # Links entfernen
RPOP queue                   # Rechts entfernen
BRPOP queue 0               # Blocking Pop

# Range
LRANGE queue 0 -1           # Alle Elemente
LLEN queue                  # Länge

Sets

# Hinzufügen
SADD tags "linux" "server" "admin"

# Mitglieder
SMEMBERS tags

# Enthält?
SISMEMBER tags "linux"

# Operationen
SINTER set1 set2            # Schnittmenge
SUNION set1 set2            # Vereinigung
SDIFF set1 set2             # Differenz

Hashes

# Setzen
HSET user:1 name "Max" age 30 city "Berlin"

# Lesen
HGET user:1 name
HGETALL user:1
HMGET user:1 name age

# Inkrementieren
HINCRBY user:1 age 1

# Alle Felder
HKEYS user:1
HVALS user:1

Sorted Sets

# Mit Score hinzufügen
ZADD leaderboard 100 "player1" 200 "player2" 150 "player3"

# Top N
ZRANGE leaderboard 0 2 WITHSCORES        # Aufsteigend
ZREVRANGE leaderboard 0 2 WITHSCORES     # Absteigend

# Rang
ZRANK leaderboard "player1"
ZSCORE leaderboard "player1"

# Bereich nach Score
ZRANGEBYSCORE leaderboard 100 200

Caching-Patterns

Cache-Aside

def get_user(user_id):
    # Erst Cache prüfen
    cached = redis.get(f"user:{user_id}")
    if cached:
        return json.loads(cached)

    # Aus DB laden
    user = db.query(f"SELECT * FROM users WHERE id = {user_id}")

    # In Cache speichern
    redis.setex(f"user:{user_id}", 3600, json.dumps(user))

    return user

Write-Through

def update_user(user_id, data):
    # DB aktualisieren
    db.execute(f"UPDATE users SET ... WHERE id = {user_id}")

    # Cache aktualisieren
    redis.setex(f"user:{user_id}", 3600, json.dumps(data))

Cache Invalidation

def invalidate_user(user_id):
    redis.delete(f"user:{user_id}")

Session Storage

PHP Sessions

; /etc/php/8.2/fpm/php.ini

session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379?auth=password"

Django Sessions

# settings.py

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.redis.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
    }
}

SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

Laravel Sessions

// .env
SESSION_DRIVER=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=password
REDIS_PORT=6379

// config/database.php
'redis' => [
    'client' => 'predis',
    'default' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => 0,
    ],
],

Pub/Sub

Publisher

# In Terminal 1
PUBLISH news "Breaking: New feature released!"

Subscriber

# In Terminal 2
SUBSCRIBE news
# Wartet auf Nachrichten

# Pattern Subscribe
PSUBSCRIBE news:*

Python Beispiel

import redis

r = redis.Redis()

# Publisher
r.publish('notifications', 'New message!')

# Subscriber
pubsub = r.pubsub()
pubsub.subscribe('notifications')

for message in pubsub.listen():
    if message['type'] == 'message':
        print(message['data'])

Persistenz

RDB (Snapshots)

# redis.conf
save 900 1      # Nach 900s wenn min. 1 Key geändert
save 300 10     # Nach 300s wenn min. 10 Keys geändert
save 60 10000   # Nach 60s wenn min. 10000 Keys geändert

dbfilename dump.rdb
dir /var/lib/redis/

AOF (Append Only File)

# redis.conf
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec   # Optionen: always, everysec, no

# AOF rewrite threshold
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

Manueller Snapshot

# Im CLI
BGSAVE              # Im Hintergrund
SAVE                # Blocking (nicht empfohlen)

# Letzter Snapshot
LASTSAVE

Replikation

Master-Replica

# Auf Replica-Server
# /etc/redis/redis.conf

replicaof 192.168.1.10 6379
masterauth MasterPassword

Replikation prüfen

# Master
INFO replication

# Output:
role:master
connected_slaves:2
slave0:ip=192.168.1.11,port=6379,state=online
slave1:ip=192.168.1.12,port=6379,state=online

Sentinel (Hochverfügbarkeit)

Sentinel-Konfiguration

# /etc/redis/sentinel.conf

sentinel monitor mymaster 192.168.1.10 6379 2
sentinel auth-pass mymaster MasterPassword
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1

Sentinel starten

redis-sentinel /etc/redis/sentinel.conf
# oder
redis-server /etc/redis/sentinel.conf --sentinel

Client-Verbindung

from redis.sentinel import Sentinel

sentinel = Sentinel([
    ('sentinel1', 26379),
    ('sentinel2', 26379),
    ('sentinel3', 26379)
], socket_timeout=0.1)

master = sentinel.master_for('mymaster', password='password')
master.set('key', 'value')

Cluster

Cluster erstellen

# Mindestens 6 Nodes (3 Master, 3 Replicas)
redis-cli --cluster create \
  192.168.1.1:6379 \
  192.168.1.2:6379 \
  192.168.1.3:6379 \
  192.168.1.4:6379 \
  192.168.1.5:6379 \
  192.168.1.6:6379 \
  --cluster-replicas 1

Node-Konfiguration

# /etc/redis/redis.conf

cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000

Cluster-Status

redis-cli cluster info
redis-cli cluster nodes

Sicherheit

Authentifizierung

# redis.conf
requirepass YourSecurePassword

# ACL (Redis 6+)
user admin on +@all ~* >AdminPassword
user reader on +@read ~cache:* >ReaderPassword

ACL-Befehle

# ACL erstellen
ACL SETUSER myuser on +GET +SET ~prefix:* >password

# ACL anzeigen
ACL LIST
ACL GETUSER myuser

Netzwerk

# Nur lokal
bind 127.0.0.1

# Bestimmte IPs
bind 127.0.0.1 192.168.1.10

# Protected Mode (wenn kein Passwort)
protected-mode yes

Monitoring

INFO-Befehl

# Alle Infos
INFO

# Spezifische Sektion
INFO memory
INFO stats
INFO replication
INFO cpu

Wichtige Metriken

# Speicher
used_memory_human
maxmemory_human
mem_fragmentation_ratio

# Performance
instantaneous_ops_per_sec
total_connections_received
rejected_connections

# Persistenz
rdb_last_save_time
aof_current_rewrite_time_sec

Redis Slowlog

# Slowlog aktivieren
CONFIG SET slowlog-log-slower-than 10000
CONFIG SET slowlog-max-len 100

# Slowlog anzeigen
SLOWLOG GET 10

Troubleshooting

Speicherprobleme

# Speicheranalyse
redis-cli --bigkeys
redis-cli MEMORY DOCTOR

# Keys nach Größe
redis-cli DEBUG OBJECT key

Verbindungsprobleme

# Verbindungen prüfen
redis-cli INFO clients

# Client-Liste
redis-cli CLIENT LIST

# Verbindung beenden
redis-cli CLIENT KILL ip:port

Latenz

# Latenz-Test
redis-cli --latency

# Intrinsische Latenz
redis-cli --intrinsic-latency 10

Zusammenfassung

| Datentyp | Verwendung | |----------|------------| | String | Einfache Werte, Counter | | List | Queues, Recent Items | | Set | Eindeutige Werte, Tags | | Hash | Objekte, Sessions | | Sorted Set | Rankings, Scores |

| Befehl | Funktion | |--------|----------| | SET/GET | String lesen/schreiben | | HSET/HGET | Hash-Felder | | LPUSH/RPOP | Queue-Operationen | | SADD/SMEMBERS | Set-Operationen | | ZADD/ZRANGE | Sorted Set |

| Port | Dienst | |------|--------| | 6379 | Redis | | 26379 | Sentinel | | 16379 | Cluster Bus |

Fazit

Redis ist extrem vielseitig und performant. Als Cache reduziert es Datenbankzugriffe drastisch, als Session-Store ermöglicht es horizontale Skalierung von Web-Anwendungen. Die verschiedenen Datentypen decken unterschiedlichste Anwendungsfälle ab. Für Hochverfügbarkeit bieten Sentinel und Cluster professionelle Lösungen. Die Einfachheit der API und die hervorragende Performance machen Redis zur ersten Wahl für In-Memory-Datenspeicherung.