Redis Hoge beschikbaarheid in productie: Sentinel-, Cluster- en Kubernetes-operators
Redis HA met Sentinel-, Clustermodus- en Kubernetes-operators
Redis is de ruggengraat van de moderne applicatie-infrastructuur. Het dient als cache, sessieopslag, berichtenmakelaar, snelheidsbegrenzer, leaderboard-engine en realtime analysepijplijn voor miljoenen applicaties wereldwijd. Eén enkele Redis-instantie kan honderdduizenden bewerkingen per seconde verwerken met een latentie van minder dan een milliseconde, maar een enkele instantie is ook een single point of fail. Wanneer Redis uitvalt, ervaren applicaties trapsgewijze fouten: cachestormen overweldigen backend-databases, sessies gaan verloren, snelheidsbegrenzers werken niet meer en real-time functies verdwijnen. Het bouwen van een Redis-implementatie met hoge beschikbaarheid is niet optioneel voor productiesystemen; het is een technische vereiste.
Deze handleiding is een uitgebreide, productiegerichte diepgaande duik in de hoge beschikbaarheid van Redis. We behandelen de basisprincipes van Redis-replicatie (asynchrone replicatie, de WAIT-opdracht en gedeeltelijke hersynchronisatie), Redis Sentinel voor automatische failover en servicedetectie, Redis Cluster voor horizontale schaling met hashslot-distributie, Kubernetes-operators (Spotahome, OpsTree en Redis Enterprise), persistentiestrategieën (RDB-snapshots, AOF en hybride persistentie), cloudbeheerde implementaties op AWS ElastiCache, Azure Cache voor Redis en GCP Memorystore, bare metal k3s-implementaties met Rancher en Longhorn, geheugenbeheer en uitzettingsbeleid, TLS-codering en ACL-gebaseerde toegangscontrole, Pub/Sub- en Streams-gedrag in HA-configuraties, Redis-modules (RedisJSON, RediSearch, RedisTimeSeries) in HA, pooling van verbindingen en clientconfiguratie voor failover-veerkracht, back-up- en herstelstrategieën, monitoring met Redis INFO, Prometheus-exporteur en Grafana-dashboards, Dragonfly en KeyDB als Redis-compatibele alternatieven, prestatieafstemming met pipelining, Lua-scripting en geheugenoptimalisatie, veelvoorkomende foutscenario's en procedures voor probleemoplossing, en capaciteitsplanning en schaalstrategieën.
Redis Basisprincipes van replicatie
Redis-replicatie is de basis waarop alle architecturen met hoge beschikbaarheid zijn gebouwd. Een Redis-masterinstantie accepteert schrijfbewerkingen en geeft deze asynchroon door aan een of meer replica-instanties. Replica's onderhouden een vrijwel realtime kopie van de masterdataset en dienen leesquery's, waardoor zowel gegevensredundantie als leesschaalbaarheid wordt geboden.
In tegenstelling tot de WAL-gebaseerde streamingreplicatie van PostgreSQL, gebruikt Redis een op commando's gebaseerd replicatieprotocol. Elke schrijfopdracht die op de master wordt uitgevoerd, wordt geserialiseerd in de replicatiestroom en verzonden naar verbonden replica's, die dezelfde opdrachten uitvoeren op hun lokale datasets. Deze aanpak is eenvoudig en efficiënt, maar heeft belangrijke implicaties voor de consistentie. Omdat replicatie standaard asynchroon is, is er altijd een venster waarin bevestigde schrijfbewerkingen op de master nog geen replica's hebben bereikt.
Asynchrone replicatie en het WAIT-commando
Redis-replicatie is standaard volledig asynchroon. De master bevestigt een schrijfactie aan de klant onmiddellijk nadat deze lokaal is toegepast, zonder te wachten tot een replica de ontvangst bevestigt. Dit geeft een maximale schrijfdoorvoer, maar introduceert een potentieel gegevensverliesvenster: als de master crasht voordat een schrijfactie een replica bereikt, gaat die schrijfactie verloren.
De opdrachtWAITbiedt een synchrone replicatieprimitief. Na het schrijven kan de clientWAIT numreplicas timeoutaanroepen om te blokkeren totdat het opgegeven aantal replica's het schrijven heeft bevestigd of de time-out is verstreken. Dit maakt Redis niet volledig synchroon:WAITgarandeert alleen dat replica's de gegevens hebben ontvangen, niet dat deze op schijf op de replica's zijn opgeslagen. Het vermindert echter de periode voor gegevensverlies aanzienlijk.
# Write a critical value and wait for 2 replicas to acknowledge
SET order:12345 '{"status":"confirmed","amount":599.99}'
WAIT 2 5000
# Returns the number of replicas that acknowledged within 5000ms
# Returns 0 if no replica acknowledged (timeout or no replicas connected)GebruikWAITselectief voor kritieke schrijfbewerkingen (financiële transacties, orderbevestigingen) terwijl u niet-kritieke schrijfbewerkingen (cache-updates, sessievernieuwingen) asynchroon laat verlopen. Dankzij de flexibiliteit per opdracht wordt de latentiestraf van volledige synchrone replicatie vermeden.
Gedeeltelijke hersynchronisatie (PSYNC)
Wanneer een replica kortstondig de verbinding verbreekt (netwerkstoring, opnieuw opstarten), is er geen volledige gegevenssetoverdracht nodig om opnieuw deel te nemen. Redis onderhoudt een replicatieachterstand – een circulaire buffer van recente schrijfopdrachten – op de master. Wanneer de replica opnieuw verbinding maakt, verzendt deze de replicatie-offset naar de master. Als de offset nog steeds binnen de achterstand ligt, verzendt de master alleen de ontbrekende opdrachten (gedeeltelijke hersynchronisatie). Als de offset buiten de backlog is gevallen, wordt een volledige hersynchronisatie geactiveerd, waarbij een RDB-snapshot wordt gegenereerd en overgedragen.
# redis.conf — Replication backlog configuration
repl-backlog-size 256mb # Size of the replication backlog buffer
repl-backlog-ttl 3600 # Seconds to retain backlog after last replica disconnects
repl-diskless-sync yes # Transfer RDB via socket instead of disk (faster for full sync)
repl-diskless-sync-delay 5 # Wait 5s for more replicas before starting diskless sync
repl-diskless-sync-period 0 # No periodic full sync
repl-diskless-load on-empty-db # Replica loads RDB from socket directly into memoryHet correct dimensioneren van de replicatieachterstand is van cruciaal belang. Het moet groot genoeg zijn om alle schrijfopdrachten te bevatten die zijn gegenereerd tijdens de langst verwachte ontkoppeling van de replica. Voor een Redis-instantie die 50 MB/s schrijfverkeer verwerkt, beslaat een achterstand van 256 MB ongeveer 5 seconden aan schrijfbewerkingen. Verhoog deze achterstand als uw replica's mogelijk langere tijd offline zijn.
Master-Replica-replicatie
configureren# redis.conf — Master configuration
bind 0.0.0.0
port 6379
protected-mode no
requirepass strong_master_password
masterauth strong_master_password
# Persistence
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes
# Replication
repl-backlog-size 256mb
repl-backlog-ttl 3600
repl-diskless-sync yes
min-replicas-to-write 1 # Refuse writes if fewer than 1 replica connected
min-replicas-max-lag 10 # Replica considered disconnected if lag > 10 seconds# redis.conf — Replica configuration
bind 0.0.0.0
port 6379
protected-mode no
requirepass strong_master_password
masterauth strong_master_password
replicaof master-host 6379
replica-read-only yes
replica-serve-stale-data yes # Serve (possibly stale) data during sync
replica-priority 100 # Lower values get promoted first by SentinelDemin-replicas-to-write- enmin-replicas-max-lag-instellingen voorkomen dat de master schrijfbewerkingen accepteert wanneer deze de duurzaamheid van gegevens op replica's niet kan garanderen. Dit is een cruciaal vangnet; zonder dit gaat een netwerkgepartitioneerde master door met het accepteren van schrijfbewerkingen die verloren gaan als Sentinel een replica promoot.
Redis Sentinel: automatische failover en servicedetectie
Redis Sentinel is een gedistribueerd systeem dat Redis-master- en replica-instanties bewaakt, masterfouten detecteert, automatische failover uitvoert door een replica tot master te promoveren, en service-detectie biedt, zodat klanten altijd de huidige master kunnen vinden. Sentinel draait als een afzonderlijk proces naast Redis en werkt via een consensusprotocol: een quorum van Sentinel-instances moet het erover eens zijn dat een master onbereikbaar is voordat de failover wordt gestart.
Sentinel-configuratie
Sentinel vereist minimaal drie instanties om één Sentinel-fout te tolereren en toch het quorum te behouden. Elke Sentinel bewaakt dezelfde Redis-master en communiceert met andere Sentinels via een roddelprotocol om overeenstemming te bereiken over de gezondheidsstatus van de master.
# /etc/redis/sentinel.conf — Sentinel instance configuration
port 26379
bind 0.0.0.0
protected-mode no
# Monitor the master named "mymaster" at 10.0.1.10:6379
# The quorum value (2) means 2 Sentinels must agree the master is down
sentinel monitor mymaster 10.0.1.10 6379 2
# Authentication
sentinel auth-pass mymaster strong_master_password
# Timing parameters
sentinel down-after-milliseconds mymaster 5000 # SDOWN after 5s of no PING response
sentinel failover-timeout mymaster 60000 # Max 60s for failover procedure
sentinel parallel-syncs mymaster 1 # Only 1 replica syncs from new master at a time
# Deny script execution for security
sentinel deny-scripts-reconfig yes
# Notification script (called on failover events)
# sentinel notification-script mymaster /opt/redis/notify.sh
# Client reconfiguration script (called when master changes)
# sentinel client-reconfig-script mymaster /opt/redis/reconfig.sh
# Logging
logfile /var/log/redis/sentinel.log
logevel notice
# Enable TLS for Sentinel communication
# tls-port 26379
# port 0
# tls-cert-file /etc/redis/tls/sentinel.crt
# tls-key-file /etc/redis/tls/sentinel.key
# tls-ca-cert-file /etc/redis/tls/ca.crt
# tls-replication yes
# tls-auth-clients optionalDe foutdetectie vanSentinel werkt in twee fasen. Ten eerste markeert een individuele Sentinel een master alsSubjectively Down (SDOWN)wanneer deze geen geldig antwoord ontvangt op PING binnendown-after-milliseconds. Wanneer een quorum van Sentinels het er vervolgens over eens is dat de master onbereikbaar is, wordt deze gemarkeerd alsObjectively Down (ODOWN)en begint het failoverproces. Eén Sentinel wordt gekozen als failoverleider, die de beste replica selecteert (op basis van prioriteit, replicatie-offset en runid), deze promoveert tot master, de resterende replica's opnieuw configureert om de nieuwe master te volgen en de Sentinel-status bijwerkt.
Sentinel Service Discovery en clientconfiguratie
Het belangrijkste voordeel van Sentinel ten opzichte van statische master-replica-opstellingen is service-ontdekking. Clients maken geen verbinding met een vast Redis-adres; ze vragen Sentinel om het huidige hoofdadres en abonneren zich op failover-meldingen. Elke grote Redis-clientbibliotheek ondersteunt Sentinel native.
# Node.js — ioredis with Sentinel support
const Redis = require('ioredis');
const redis = new Redis({
sentinels: [
{ host: '10.0.1.20', port: 26379 },
{ host: '10.0.1.21', port: 26379 },
{ host: '10.0.1.22', port: 26379 }
],
name: 'mymaster',
password: 'strong_master_password',
sentinelPassword: 'sentinel_password',
db: 0,
retryStrategy(times) {
const delay = Math.min(times * 200, 5000);
return delay;
},
reconnectOnError(err) {
const targetError = 'READONLY';
if (err.message.includes(targetError)) {
return true; // Reconnect on READONLY error (failover happened)
}
return false;
},
maxRetriesPerRequest: 3,
enableReadyCheck: true,
connectTimeout: 10000,
lazyConnect: false
});
redis.on('connect', () => console.log('Connected to Redis master'));
redis.on('error', (err) => console.error('Redis error:', err));
redis.on('+switch-master', (msg) => {
console.log('Master switched:', msg);
});# Python — redis-py with Sentinel support
from redis.sentinel import Sentinel
import redis
sentinel = Sentinel(
[('10.0.1.20', 26379), ('10.0.1.21', 26379), ('10.0.1.22', 26379)],
socket_timeout=5,
password='strong_master_password',
sentinel_kwargs={'password': 'sentinel_password'}
)
# Get a connection to the current master (for writes)
master = sentinel.master_for(
'mymaster',
socket_timeout=5,
retry_on_timeout=True,
db=0
)
# Get a connection to a replica (for reads)
replica = sentinel.slave_for(
'mymaster',
socket_timeout=5,
db=0
)
# Usage
master.set('session:user123', '{"logged_in": true}')
result = replica.get('session:user123')
print(result)// Go — go-redis with Sentinel support
package main
import (
"context"
"fmt"
"time"
"github.com/redis/go-redis/v9"
)
func main() {
ctx := context.Background()
rdb := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: "mymaster",
SentinelAddrs: []string{"10.0.1.20:26379", "10.0.1.21:26379", "10.0.1.22:26379"},
Password: "strong_master_password",
SentinelPassword: "sentinel_password",
DB: 0,
DialTimeout: 10 * time.Second,
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
PoolSize: 50,
MinIdleConns: 10,
MaxRetries: 3,
MinRetryBackoff: 200 * time.Millisecond,
MaxRetryBackoff: 5 * time.Second,
})
defer rdb.Close()
err := rdb.Set(ctx, "key", "value", 5*time.Minute).Err()
if err != nil {
fmt.Printf("Error: %v
", err)
return
}
val, err := rdb.Get(ctx, "key").Result()
if err != nil {
fmt.Printf("Error: %v
", err)
return
}
fmt.Printf("key = %s
", val)
}Redis-cluster: horizontaal schalen met hash-slots
Terwijl Sentinel hoge beschikbaarheid biedt voor een enkele dataset, biedt Redis Cluster zowel HA als horizontale schaling. Redis Cluster verdeelt gegevens over meerdere masternodes met behulp van een hashslot-mechanisme: de sleutelruimte is verdeeld in 16.384 hashslots, en elke master is verantwoordelijk voor een subset van die slots. Elke master heeft een of meer replica's voor failover. Het cluster biedt gezamenlijk automatische sharding, ingebouwde failover en de mogelijkheid om zowel opslag als doorvoer lineair te schalen door knooppunten toe te voegen.
Een Redis-cluster opzetten
# Create a 6-node Redis Cluster (3 masters + 3 replicas)
# Each node needs a redis.conf with cluster-enabled
# redis.conf for each cluster node (adjust port per node)
port 7000
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes
requirepass cluster_password
masterauth cluster_password
bind 0.0.0.0
protected-mode no
repl-backlog-size 256mb
# Start all 6 Redis instances
redis-server /etc/redis/7000.conf
redis-server /etc/redis/7001.conf
# ... repeat for all 6 nodes
# Create the cluster
redis-cli --cluster create \
10.0.1.10:7000 10.0.1.11:7000 10.0.1.12:7000 \
10.0.1.13:7000 10.0.1.14:7000 10.0.1.15:7000 \
--cluster-replicas 1 \
-a cluster_password
# Verify cluster status
redis-cli -c -h 10.0.1.10 -p 7000 -a cluster_password cluster info
redis-cli -c -h 10.0.1.10 -p 7000 -a cluster_password cluster nodesHerharding en bediening met meerdere toetsen
Resharding verplaatst hash-slots tussen masters om gegevens opnieuw in evenwicht te brengen na het toevoegen of verwijderen van knooppunten. Tijdens het opnieuw harden kunnen sleutels in migrerende slots ASK-omleidingen ontvangen, die de client transparant afhandelt.
# Add a new node to the cluster
redis-cli --cluster add-node 10.0.1.16:7000 10.0.1.10:7000 -a cluster_password
# Reshard slots to the new node
redis-cli --cluster reshard 10.0.1.10:7000 \
--cluster-from all \
--cluster-to NEW_NODE_ID \
--cluster-slots 4096 \
--cluster-yes \
-a cluster_password
# Rebalance the cluster automatically
redis-cli --cluster rebalance 10.0.1.10:7000 -a cluster_password
# Check cluster slot distribution
redis-cli -c -h 10.0.1.10 -p 7000 -a cluster_password cluster slotsMulti-key-bewerkingen in Redis Cluster werken alleen als alle betrokken sleutels zich in hetzelfde hash-slot bevinden. Gebruik hashtags om ervoor te zorgen dat gerelateerde sleutels aan hetzelfde slot worden toegewezen:{user:123}.profileen{user:123}.sessionshashen beide opuser:123, waardoor ze gegarandeerd op hetzelfde knooppunt terechtkomen. Dit maakt MGET-, MSET-, transacties- en Lua-scripts mogelijk voor gerelateerde sleutels.
# Hash tags ensure these keys are in the same slot
SET {order:5000}.details '{"item":"widget","qty":3}'
SET {order:5000}.payment '{"method":"card","status":"paid"}'
SET {order:5000}.shipping '{"carrier":"fedex","tracking":"FX123"}'
# Multi-key operations work because all keys share the {order:5000} hash tag
MGET {order:5000}.details {order:5000}.payment {order:5000}.shipping
# Transaction across same-slot keys
MULTI
SET {order:5000}.details '{"item":"widget","qty":3,"status":"confirmed"}'
SET {order:5000}.payment '{"method":"card","status":"captured"}'
EXECRedis-operator voor Kubernetes
Het uitvoeren van Redis in Kubernetes vereist een zorgvuldige omgang met persistente opslag, netwerkidentiteit, soepele failover en configuratiebeheer. Kubernetes-operators coderen deze operationele kennis in aangepaste controllers die Redis-clusters declaratief beheren via Custom Resource Definitions (CRDs).
Spotahome Redis-operator
De Spotahome-operator (ook bekend als redis-operator) is een volwassen, veelgebruikte operator voor het implementeren van Redis Sentinel-gebaseerde HA in Kubernetes. Het beheert Redis-masterreplicasets met op Sentinel gebaseerde failover.
# Install the Spotahome Redis Operator
helm repo add spotahome https://spotahome.github.io/redis-operator
helm install redis-operator spotahome/redis-operator \
--namespace redis-system --create-namespace
# RedisFailover CRD — 3 Redis instances + 3 Sentinels
apiVersion: databases.spotahome.com/v1
kind: RedisFailover
metadata:
name: redis-ha
namespace: production
spec:
sentinel:
replicas: 3
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
customConfig:
down-after-milliseconds: "5000"
failover-timeout: "60000"
redis:
replicas: 3
resources:
requests:
cpu: "2"
memory: 8Gi
limits:
cpu: "4"
memory: 16Gi
storage:
persistentVolumeClaim:
metadata:
name: redis-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: longhorn
customConfig:
maxmemory: "6gb"
maxmemory-policy: "allkeys-lru"
save: "900 1 300 10 60 10000"
appendonly: "yes"
appendfsync: "everysec"
aof-use-rdb-preamble: "yes"
repl-backlog-size: "256mb"
exporter:
enabled: true
image: oliver006/redis_exporter:latest
args:
- --include-system-metricsOpsTree Redis-operator
De OpsTree-operator ondersteunt zowel Redis Sentinel-topologieën (standalone HA) als Redis Cluster-topologieën (sharded HA), waardoor deze veelzijdiger is voor verschillende gebruiksscenario's.
# Install the OpsTree Redis Operator
helm repo add ot-helm https://ot-container-kit.github.io/helm-charts/
helm install redis-operator ot-helm/redis-operator \
--namespace redis-system --create-namespace
# Redis Cluster CRD — 3 masters + 3 replicas
apiVersion: redis.redis.opstreelabs.in/v1beta2
kind: RedisCluster
metadata:
name: redis-cluster
namespace: production
spec:
clusterSize: 3
clusterVersion: v7
persistenceEnabled: true
kubernetesConfig:
image: redis:7.2-alpine
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: "2"
memory: 8Gi
limits:
cpu: "4"
memory: 16Gi
redisLeader:
replicas: 3
redisConfig:
additionalRedisConfig: |
maxmemory 6gb
maxmemory-policy allkeys-lru
appendonly yes
appendfsync everysec
redisFollower:
replicas: 3
redisConfig:
additionalRedisConfig: |
maxmemory 6gb
replica-read-only yes
storage:
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: longhorn
redisExporter:
enabled: true
image: quay.io/opstree/redis-exporter:v1.44.0Redis Enterprise-operator
Redis Enterprise biedt een commerciële Kubernetes-operator geavanceerde functies, waaronder Active-Active geo-replicatie (CRDTs), ondersteuning voor Redis-modules, auto-tiering (RAM + flash) en geautomatiseerd clusterbeheer. Het is de aanbevolen optie voor organisaties die SLA's en ondersteuning op bedrijfsniveau nodig hebben.
# Redis Enterprise Operator CRD
apiVersion: app.redislabs.com/v1
kind: RedisEnterpriseCluster
metadata:
name: redis-enterprise
namespace: redis-enterprise
spec:
nodes: 3
persistentSpec:
enabled: true
storageClassName: longhorn
volumeSize: 100Gi
redisEnterpriseNodeResources:
limits:
cpu: "8"
memory: 32Gi
requests:
cpu: "4"
memory: 16Gi
uiServiceType: ClusterIP
servicesRiggerSpec:
databaseServiceType: ClusterIP
---
apiVersion: app.redislabs.com/v1alpha1
kind: RedisEnterpriseDatabase
metadata:
name: redis-ha-db
namespace: redis-enterprise
spec:
memorySize: 10GB
replication: true
shardCount: 3
persistence: aofEverySecond
tlsMode: enabled
modulesList:
- name: search
version: latest
- name: json
version: latestpersistentiestrategieën: RDB, AOF en hybride
Redis biedt drie persistentiemechanismen. Het kiezen van de juiste strategie is afhankelijk van uw herstelpuntdoelstelling (RPO), prestatievereisten en opslagbeperkingen.
RDB-snapshotsmaakt op geconfigureerde intervallen point-in-time snapshots van de gehele dataset. Ze zijn compact, snel te laden bij opnieuw opstarten en ideaal voor back-ups. Gegevens die tussen momentopnamen worden geschreven, gaan echter verloren bij een crash. RDB maakt gebruik van een gevorkt onderliggend proces, dus het maken van snapshots blokkeert niet de belangrijkste Redis-thread, maar de fork zelf kan een latentiepiek veroorzaken bij grote datasets als gevolg van de toewijzing van kopieer-op-schrijfgeheugen.
AOF (Append Only File)registreert elke schrijfbewerking naar schijf. Het biedt een veel betere duurzaamheid dan RDB: metappendfsync everysecverlies je maximaal één seconde aan gegevens bij een crash. Metappendfsync alwaysverliest u niets, maar wel tegen aanzienlijke prestatiekosten. AOF-bestanden zijn groter dan RDB en worden langzamer geladen bij opnieuw opstarten.
Hybride persistentie(de aanbevolen aanpak) combineert beide:aof-use-rdb-preamble yesschrijft een RDB-snapshot aan het begin van het AOF-bestand, gevolgd door AOF-items voor daaropvolgende schrijfbewerkingen. Dit zorgt voor snelle opstarttijden (RDB-sectie) met een sterke duurzaamheid (AOF-sectie).
# redis.conf — Hybrid persistence (recommended for production)
# RDB snapshots
save 900 1 # Snapshot if at least 1 write in 900 seconds
save 300 10 # Snapshot if at least 10 writes in 300 seconds
save 60 10000 # Snapshot if at least 10000 writes in 60 seconds
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/redis
# AOF
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec # Best balance of durability and performance
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-use-rdb-preamble yes # Hybrid: RDB preamble + AOF tail
aof-timestamp-enabled yes # Enable timestamps for PITR (Redis 7+)
# Recovery options
rdb-del-sync-files no
aof-load-truncated yesCloudbeheerde Redis-implementaties
AWS ElastiCache voor Redis
AWS ElastiCache biedt volledig beheerde Redis met twee HA-modi:Clustermodus uitgeschakeld(enkele shard, maximaal 5 replica's, Sentinel-achtige failover) enClustermodus ingeschakeld(maximaal 500 shards, elk met maximaal 5 replica's, hash-slotdistributie). Global Datastore biedt replicatie tussen regio's voor noodherstel.
# AWS CLI — Create ElastiCache Redis Cluster Mode Enabled
aws elasticache create-replication-group \
--replication-group-id redis-ha-prod \
--replication-group-description "Production Redis HA Cluster" \
--engine redis \
--engine-version 7.1 \
--cache-node-type cache.r7g.2xlarge \
--num-node-groups 3 \
--replicas-per-node-group 2 \
--automatic-failover-enabled \
--multi-az-enabled \
--at-rest-encryption-enabled \
--transit-encryption-enabled \
--auth-token strong_auth_token \
--cache-subnet-group-name redis-subnet-group \
--security-group-ids sg-0123456789abcdef0 \
--snapshot-retention-limit 7 \
--snapshot-window "03:00-05:00" \
--preferred-maintenance-window "sun:05:00-sun:07:00" \
--cache-parameter-group-name redis-ha-params \
--log-delivery-configurations '[
{"LogType":"slow-log","DestinationType":"cloudwatch-logs","DestinationDetails":{"CloudWatchLogsDetails":{"LogGroup":"/aws/elasticache/redis-ha-prod"}}},
{"LogType":"engine-log","DestinationType":"cloudwatch-logs","DestinationDetails":{"CloudWatchLogsDetails":{"LogGroup":"/aws/elasticache/redis-ha-prod"}}}
]'
# Create Global Datastore for cross-region DR
aws elasticache create-global-replication-group \
--global-replication-group-id-suffix redis-global \
--primary-replication-group-id redis-ha-prod
# Add secondary region
aws elasticache create-replication-group \
--replication-group-id redis-ha-dr \
--replication-group-description "DR Redis in eu-west-2" \
--global-replication-group-id ldgnf-redis-global \
--cache-node-type cache.r7g.2xlarge \
--num-node-groups 3 \
--replicas-per-node-group 1 \
--region eu-west-2
# Custom parameter group for HA tuning
aws elasticache create-cache-parameter-group \
--cache-parameter-group-name redis-ha-params \
--cache-parameter-group-family redis7 \
--description "HA-optimised Redis 7 parameters"
aws elasticache modify-cache-parameter-group \
--cache-parameter-group-name redis-ha-params \
--parameter-name-values \
"ParameterName=maxmemory-policy,ParameterValue=allkeys-lru" \
"ParameterName=timeout,ParameterValue=300" \
"ParameterName=tcp-keepalive,ParameterValue=60" \
"ParameterName=activedefrag,ParameterValue=yes"Azure-cache voor Redis
Azure Cache voor Redis biedt drie niveaus: Basic (geen replicatie), Standard (gerepliceerd) en Premium/Enterprise. De Premium-laag ondersteunt clustering, geo-replicatie, zoneredundantie, VNet-injectie en gegevenspersistentie. De Enterprise-laag voegt Redis-modules en Active-Active geodistributie toe.
# Azure CLI — Create Premium Azure Cache for Redis with clustering
az redis create \
--resource-group redis-ha-rg \
--name redis-ha-prod \
--location westeurope \
--sku Premium \
--vm-size P3 \
--shard-count 3 \
--replicas-per-master 1 \
--zones 1 2 3 \
--minimum-tls-version 1.2 \
--redis-version 7
# Enable geo-replication (link primary to secondary)
az redis server-link create \
--name redis-ha-prod \
--resource-group redis-ha-rg \
--server-to-link /subscriptions/.../redis-ha-dr \
--replication-role Secondary
# Configure data persistence
az redis update \
--name redis-ha-prod \
--resource-group redis-ha-rg \
--set redisConfiguration.rdb-backup-enabled=true \
--set redisConfiguration.rdb-backup-frequency=60 \
--set redisConfiguration.rdb-storage-connection-string="DefaultEndpointsProtocol=https;..."
# Enable diagnostics
az monitor diagnostic-settings create \
--name redis-diagnostics \
--resource /subscriptions/.../redis-ha-prod \
--workspace /subscriptions/.../log-analytics-workspace \
--metrics '[{"category":"AllMetrics","enabled":true}]'GCP-geheugenopslag voor Redis
GCP biedt twee Memorystore-lagen:Standaard(enkel exemplaar met automatische failover-replica) enRedis Cluster(sharded, volledig beheerd cluster met automatische schaling). De Standard-laag is geschikt voor de meeste HA-gebruiksscenario's, terwijl Redis Cluster grote datasets verwerkt die horizontaal schalen vereisen.
# GCP — Create Standard tier Memorystore (HA with auto-failover)
gcloud redis instances create redis-ha-prod \
--size=26 \
--region=europe-west1 \
--zone=europe-west1-b \
--alternative-zone=europe-west1-c \
--tier=standard \
--redis-version=redis_7_2 \
--redis-config="maxmemory-policy=allkeys-lru,activedefrag=yes" \
--network=projects/my-project/global/networks/vpc-main \
--transit-encryption-mode=SERVER_AUTHENTICATION \
--enable-auth \
--persistence-mode=RDB \
--rdb-snapshot-period=12h \
--rdb-snapshot-start-time="2026-04-12T03:00:00Z" \
--maintenance-window-day=SUNDAY \
--maintenance-window-hour=4
# GCP — Create Memorystore Redis Cluster
gcloud redis clusters create redis-cluster-prod \
--region=europe-west1 \
--shard-count=3 \
--replica-count=1 \
--network=projects/my-project/global/networks/vpc-main \
--transit-encryption-mode=SERVER_AUTHENTICATIONRedis-implementatie voor meerdere regio's
Redis-implementatie in meerdere regio's is essentieel voor noodherstel en wereldwijde latentiereductie. De aanpak verschilt per architectuur: Redis Enterprise gebruikt Active-Active met CRDT's (Conflict-free Replicated Data Types) voor echte multi-master schrijfbewerkingen, terwijl open-source Redis en cloudbeheerde services actief-passieve replicatie gebruiken met leesreplica's in secundaire regio's.
Blank metaal k3s/Rancher met Longhorn
Voor organisaties die hun eigen hardware gebruiken, biedt de implementatie van Redis HA op bare metal k3s volledige controle over de infrastructuur, elimineert het de lock-in van cloudleveranciers en kan het aanzienlijk kosteneffectiever zijn voor grootschalige implementaties. k3s is een lichtgewicht, gecertificeerde Kubernetes-distributie, ideaal voor edge- en bare metal-omgevingen, terwijl Rancher een beheervlak biedt voor multi-clusteroperaties.
k3s Installatie en Redis Operator Implementatie
# Install k3s on the first server node
curl -sfL https://get.k3s.io | K3S_TOKEN=redis-cluster-token \
INSTALL_K3S_EXEC="server --cluster-init --disable traefik --disable servicelb" sh -
# Join additional server nodes
curl -sfL https://get.k3s.io | K3S_TOKEN=redis-cluster-token \
K3S_URL=https://10.0.0.1:6443 \
INSTALL_K3S_EXEC="server" sh -
# Install Longhorn for distributed block storage
helm repo add longhorn https://charts.longhorn.io
helm install longhorn longhorn/longhorn \
--namespace longhorn-system --create-namespace \
--set defaultSettings.defaultDataPath=/mnt/longhorn \
--set defaultSettings.replicaCount=3 \
--set defaultSettings.storageMinimalAvailablePercentage=15
# Install MetalLB for bare-metal LoadBalancer services
helm repo add metallb https://metallb.github.io/metallb
helm install metallb metallb/metallb --namespace metallb-system --create-namespace
# Configure MetalLB IP address pool
kubectl apply -f - <Redis HA Helm Waarden voor k3s
# values-redis-ha.yaml — Helm values for Redis HA on k3s/Longhorn
redis:
replicas: 3
resources:
requests:
cpu: "2"
memory: 8Gi
limits:
cpu: "4"
memory: 16Gi
storage:
persistentVolumeClaim:
metadata:
name: redis-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: longhorn
customConfig:
maxmemory: "6gb"
maxmemory-policy: "allkeys-lru"
save: "900 1 300 10 60 10000"
appendonly: "yes"
appendfsync: "everysec"
aof-use-rdb-preamble: "yes"
repl-backlog-size: "256mb"
tcp-keepalive: "60"
timeout: "300"
hz: "10"
activedefrag: "yes"
exporter:
enabled: true
image: oliver006/redis_exporter:latest
sentinel:
replicas: 3
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
customConfig:
down-after-milliseconds: "5000"
failover-timeout: "60000"
parallel-syncs: "1"
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/component
operator: In
values:
- redis
topologyKey: kubernetes.io/hostnameGeheugenbeheer en uitzettingsbeleid
Redis slaat alle gegevens op in het geheugen, waardoor geheugenbeheer de meest kritische operationele zorg wordt. Wanneer Redis de geconfigureerdemaxmemory-limiet bereikt, moet het beslissen wat er met inkomende schrijfopdrachten moet gebeuren. Het uitzettingsbeleid controleert dit gedrag.
# redis.conf — Memory management
maxmemory 6gb
maxmemory-policy allkeys-lru
# Available eviction policies:
# noeviction — Return errors on writes when memory limit reached
# allkeys-lru — Evict least recently used keys (general-purpose cache)
# allkeys-lfu — Evict least frequently used keys (better for skewed access patterns)
# volatile-lru — Evict LRU keys with TTL set
# volatile-lfu — Evict LFU keys with TTL set
# volatile-ttl — Evict keys with shortest TTL first
# allkeys-random — Evict random keys
# volatile-random — Evict random keys with TTL set
# Active defragmentation (Redis 4.0+)
activedefrag yes
active-defrag-enabled yes
active-defrag-ignore-bytes 100mb
active-defrag-threshold-lower 10
active-defrag-threshold-upper 100
active-defrag-cycle-min 1
active-defrag-cycle-max 25
active-defrag-max-scan-fields 1000
# Memory usage monitoring
# redis-cli INFO memory
# Key metrics:
# used_memory — Total bytes allocated by Redis
# used_memory_rss — Resident set size (OS-level memory)
# mem_fragmentation_ratio — RSS / used_memory (should be close to 1.0)
# maxmemory — Configured memory limit
# evicted_keys — Total keys evicted due to maxmemoryVoor HA-implementaties stelt umaxmemoryin op ongeveer 75% van het beschikbare RAM-geheugen van het knooppunt. De resterende 25% biedt plaats aan de replicatie-uitvoerbuffer, de AOF-herschrijfbuffer, het kopieer-op-schrijfgeheugen tijdens RDB-snapshots en de overhead van het besturingssysteem. Voor een pod van 16 GB stelt u max. geheugen in op 12 GB. Voor een bare metal-server van 64 GB stelt u deze in op 48 GB.
TLS-codering en ACL's
Productie Redis-implementaties moeten gegevens tijdens de overdracht versleutelen met TLS en een fijnmazige toegangscontrole afdwingen met ACL's (Access Control Lists), geïntroduceerd in Redis 6.0.
# redis.conf — TLS configuration
tls-port 6380
port 0 # Disable non-TLS port entirely
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt
tls-auth-clients optional # Require client certificates (mutual TLS)
tls-replication yes # Encrypt replication traffic
tls-cluster yes # Encrypt cluster bus traffic
tls-protocols "TLSv1.3" # Only allow TLS 1.3
# ACL configuration (Redis 6.0+)
# user on|off [>password] [~pattern] [+command|-command] [&channel]
user default off # Disable the default user
user admin on >strong_admin_pass ~* +@all
user appuser on >app_pass ~app:* ~session:* ~cache:* +@read +@write +@connection -@admin -@dangerous
user readonly on >readonly_pass ~* +@read +@connection -@write -@admin
user replicator on >repl_pass +psync +replconf +ping
# Load ACL from external file
aclfile /etc/redis/users.acl Pub/Sub en streams in HA-instellingen
Redis Pub/Sub en Streams gedragen zich anders in HA-configuraties. Het begrijpen van deze verschillen is essentieel voor het bouwen van betrouwbare, gebeurtenisgestuurde systemen.
Pub/Sub-berichten zijn 'fire-and-forget': ze worden niet bewaard, niet gerepliceerd en niet gebufferd. In een op Sentinel gebaseerde HA-opstelling ontvangen abonnees die zijn aangesloten op de master normaal berichten, maar tijdens een failover heeft de nieuwe master geen kennis van eerdere abonnementen. Klanten moeten zich opnieuw abonneren nadat ze opnieuw verbinding hebben gemaakt. Met Redis Cluster worden Pub/Sub-berichten uitgezonden naar alle knooppunten in het cluster, zodat abonnees die op een willekeurig knooppunt zijn aangesloten, gepubliceerde berichten ontvangen (hoewel dit verkeer tussen de knooppunten genereert).
Redis Streamszijn een persistente, gerepliceerde datastructuur die zorgt voor een betrouwbare bezorging van berichten in HA-omgevingen. Stream-items worden gerepliceerd naar replica's via het normale replicatiemechanisme, overleven failovers en ondersteunen consumentengroepen met ten minste één keer leveringssemantiek. Voor HA-berichten moet altijd de voorkeur worden gegeven aan Streams boven Pub/Sub.
# Redis Streams with consumer groups — HA-safe message processing
# Create a stream and consumer group
XGROUP CREATE events:orders orders-processors $ MKSTREAM
# Produce events
XADD events:orders * action "order_placed" order_id "12345" amount "599.99"
XADD events:orders * action "order_placed" order_id "12346" amount "149.99"
# Consume events (in consumer group — at-least-once delivery)
XREADGROUP GROUP orders-processors worker-1 COUNT 10 BLOCK 5000 STREAMS events:orders >
# Acknowledge processed events
XACK events:orders orders-processors 1681234567890-0
# Check pending messages (unacknowledged)
XPENDING events:orders orders-processors - + 10
# Claim abandoned messages (from a dead consumer)
XAUTOCLAIM events:orders orders-processors worker-2 60000 0-0 COUNT 10
# Trim stream to prevent unbounded growth
XTRIM events:orders MAXLEN ~ 100000Redis-modules in HA
Redis-modules breiden Redis uit met gespecialiseerde datastructuren en functionaliteit. De drie meest populaire – RedisJSON, RediSearch en RedisTimeSeries – werken met replicatie en Sentinel, maar hebben specifieke overwegingen bij HA-implementaties.
# redis.conf — Loading modules
loadmodule /opt/redis-stack/lib/rejson.so
loadmodule /opt/redis-stack/lib/redisearch.so
loadmodule /opt/redis-stack/lib/redistimeseries.so
# Modules are replicated to replicas via the command stream
# Ensure the same modules are installed on all nodes (master + replicas)
# RedisJSON — store and query JSON documents
JSON.SET user:1001 $ '{"name":"Alice","email":"alice@example.com","orders":42}'
JSON.GET user:1001 $.name
# RediSearch — full-text search with indexing
FT.CREATE idx:users ON JSON PREFIX 1 user: SCHEMA $.name AS name TEXT $.email AS email TAG $.orders AS orders NUMERIC
FT.SEARCH idx:users "@name:Alice"
# RedisTimeSeries — time-series data
TS.CREATE metrics:cpu:node1 RETENTION 86400000 LABELS host node1 metric cpu
TS.ADD metrics:cpu:node1 * 73.5
TS.RANGE metrics:cpu:node1 - + AGGREGATION avg 60000Wanneer u Redis Stack (de modulebundel) in HA uitvoert, zorg er dan voor dat op alle knooppunten (master en replica's) identieke moduleversies zijn geïnstalleerd. Moduleopdrachten worden gerepliceerd via de standaardreplicatiestroom, dus replica's moeten deze kunnen uitvoeren. Na een failover bestaan er RediSearch-indexen op de gepromote replica en worden query's onmiddellijk uitgevoerd.
Verbindingspooling en clientconfiguratie voor HA
Een goede pooling van verbindingen is essentieel voor de prestaties en veerkracht van de Redis HA. Verbindingspools verminderen de overhead bij het tot stand brengen van TCP-verbindingen, bieden automatische logica voor opnieuw proberen en maken een soepele failover-afhandeling mogelijk.
# Node.js — ioredis connection pool with cluster mode
const Redis = require('ioredis');
// Cluster mode connection
const cluster = new Redis.Cluster(
[
{ host: '10.0.1.10', port: 7000 },
{ host: '10.0.1.11', port: 7000 },
{ host: '10.0.1.12', port: 7000 }
],
{
redisOptions: {
password: 'cluster_password',
connectTimeout: 10000,
maxRetriesPerRequest: 3
},
scaleReads: 'slave', // Route reads to replicas
clusterRetryStrategy(times) {
return Math.min(times * 200, 5000);
},
slotsRefreshTimeout: 2000,
slotsRefreshInterval: 5000,
enableOfflineQueue: true,
enableReadyCheck: true,
natMap: {} // For NAT/port-forwarded environments
}
);
cluster.on('error', (err) => console.error('Cluster error:', err));
cluster.on('node error', (err, address) => {
console.error(`Node ${address} error:`, err);
});# Python — redis-py connection pool with cluster mode
from redis.cluster import RedisCluster
from redis.backoff import ExponentialBackoff
from redis.retry import Retry
retry = Retry(ExponentialBackoff(cap=5, base=0.1), retries=5)
rc = RedisCluster(
startup_nodes=[
{"host": "10.0.1.10", "port": 7000},
{"host": "10.0.1.11", "port": 7000},
{"host": "10.0.1.12", "port": 7000}
],
password="cluster_password",
decode_responses=True,
read_from_replicas=True,
retry=retry,
retry_on_timeout=True,
socket_timeout=5,
socket_connect_timeout=5,
max_connections=50,
health_check_interval=30
)
rc.set("key", "value")
print(rc.get("key"))// Go — go-redis cluster client with connection pooling
package main
import (
"context"
"time"
"github.com/redis/go-redis/v9"
)
func NewRedisCluster() *redis.ClusterClient {
return redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{
"10.0.1.10:7000",
"10.0.1.11:7000",
"10.0.1.12:7000",
},
Password: "cluster_password",
ReadOnly: true,
RouteRandomly: true,
RouteByLatency: false,
PoolSize: 50,
MinIdleConns: 10,
DialTimeout: 10 * time.Second,
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
PoolTimeout: 10 * time.Second,
MaxRetries: 5,
MinRetryBackoff: 200 * time.Millisecond,
MaxRetryBackoff: 5 * time.Second,
})
}Back-up- en herstelstrategieën
Zelfs met HA-replicatie zijn regelmatige back-ups essentieel voor noodherstel, compliance en bescherming tegen logische fouten (per ongeluk FLUSHALL, slechte schrijfbewerkingen van applicaties). Redis-back-ups zijn gebaseerd op RDB-snapshots en AOF-bestanden.
#!/bin/bash
# redis-backup.sh — Automated Redis backup script
REDIS_HOST="10.0.1.10"
REDIS_PORT="6379"
REDIS_PASS="strong_master_password"
BACKUP_DIR="/backups/redis"
S3_BUCKET="s3://redis-backups-prod"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
# Trigger RDB snapshot on the master
redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" -a "$REDIS_PASS" BGSAVE
# Wait for background save to complete
while [ "$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASS LASTSAVE)" = "$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASS LASTSAVE)" ]; do
sleep 1
done
sleep 2
# Copy the RDB file
RDB_FILE=$(redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" -a "$REDIS_PASS" CONFIG GET dir | tail -1)
cp "${RDB_FILE}/dump.rdb" "${BACKUP_DIR}/dump_${DATE}.rdb"
# Compress and upload to S3
gzip "${BACKUP_DIR}/dump_${DATE}.rdb"
aws s3 cp "${BACKUP_DIR}/dump_${DATE}.rdb.gz" "${S3_BUCKET}/daily/dump_${DATE}.rdb.gz" \
--storage-class STANDARD_IA
# Cleanup old local backups
find "$BACKUP_DIR" -name "dump_*.rdb.gz" -mtime +$RETENTION_DAYS -delete
# Verify backup integrity
redis-check-rdb "${BACKUP_DIR}/dump_${DATE}.rdb.gz" && \
echo "Backup verified: dump_${DATE}.rdb.gz" || \
echo "ERROR: Backup verification failed!"
echo "Backup complete: ${BACKUP_DIR}/dump_${DATE}.rdb.gz"# Restore from RDB backup
# 1. Stop Redis
systemctl stop redis
# 2. Replace the RDB file
gunzip /backups/redis/dump_20260412_030000.rdb.gz
cp /backups/redis/dump_20260412_030000.rdb /data/redis/dump.rdb
chown redis:redis /data/redis/dump.rdb
# 3. Disable AOF temporarily (if enabled) to prevent AOF overriding RDB on startup
redis-cli -a password CONFIG SET appendonly no
# 4. Start Redis (loads RDB)
systemctl start redis
# 5. Re-enable AOF and rewrite it from the loaded data
redis-cli -a password CONFIG SET appendonly yes
redis-cli -a password BGREWRITEAOF-bewaking met Redis INFO, Prometheus en Grafana
Uitgebreide monitoring vormt de basis voor operationele uitmuntendheid voor Redis HA. Redis maakt rijke interne statistieken zichtbaar via de opdrachtINFO, die de Prometheus Redis-exporteur vertaalt in tijdreeksstatistieken voor Grafana-dashboards en waarschuwingen.
# Key Redis INFO sections for HA monitoring
redis-cli -a password INFO replication
# role:master
# connected_slaves:2
# slave0:ip=10.0.1.11,port=6379,state=online,offset=1234567,lag=0
# slave1:ip=10.0.1.12,port=6379,state=online,offset=1234560,lag=1
# master_replid:abc123...
# master_repl_offset:1234567
# repl_backlog_size:268435456
# repl_backlog_first_byte_offset:1000000
redis-cli -a password INFO memory
# used_memory:6442450944
# used_memory_human:6.00G
# used_memory_rss:6879707136
# mem_fragmentation_ratio:1.07
# maxmemory:6442450944
# maxmemory_policy:allkeys-lru
# evicted_keys:12345
redis-cli -a password INFO stats
# total_connections_received:50000
# total_commands_processed:12345678
# instantaneous_ops_per_sec:85432
# keyspace_hits:11000000
# keyspace_misses:1345678
# expired_keys:500000
# evicted_keys:12345
redis-cli -a password INFO clients
# connected_clients:150
# blocked_clients:0
# maxclients:10000# Prometheus Redis Exporter deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-exporter
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: redis-exporter
template:
metadata:
labels:
app: redis-exporter
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9121"
spec:
containers:
- name: redis-exporter
image: oliver006/redis_exporter:latest
args:
- --redis.addr=redis://redis-ha-master:6379
- --redis.password=$(REDIS_PASSWORD)
- --include-system-metrics
- --is-cluster
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: password
ports:
- containerPort: 9121
name: metrics
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi# PrometheusRule for Redis HA alerts
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: redis-ha-alerts
namespace: monitoring
spec:
groups:
- name: redis-availability
rules:
- alert: RedisDown
expr: redis_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Redis instance {{ $labels.instance }} is down"
- alert: RedisReplicaDisconnected
expr: redis_connected_slaves < 2
for: 2m
labels:
severity: warning
annotations:
summary: "Redis master has fewer than 2 connected replicas"
- alert: RedisReplicationLagHigh
expr: redis_replication_lag > 5
for: 3m
labels:
severity: warning
annotations:
summary: "Redis replication lag exceeds 5 seconds on {{ $labels.instance }}"
- alert: RedisMemoryUsageHigh
expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.9
for: 5m
labels:
severity: warning
annotations:
summary: "Redis memory usage above 90% on {{ $labels.instance }}"
- alert: RedisEvictionsHigh
expr: rate(redis_evicted_keys_total[5m]) > 100
for: 5m
labels:
severity: warning
annotations:
summary: "Redis evicting keys at >100/s on {{ $labels.instance }}"
- alert: RedisKeyspaceHitRateLow
expr: redis_keyspace_hits_total / (redis_keyspace_hits_total + redis_keyspace_misses_total) < 0.8
for: 10m
labels:
severity: info
annotations:
summary: "Redis cache hit rate below 80% on {{ $labels.instance }}"
- alert: RedisSentinelDown
expr: redis_sentinel_master_status != 1
for: 1m
labels:
severity: critical
annotations:
summary: "Redis Sentinel reports master unhealthy"
- name: redis-performance
rules:
- alert: RedisSlowlogGrowing
expr: increase(redis_slowlog_length[5m]) > 10
for: 5m
labels:
severity: warning
annotations:
summary: "Redis slow log growing rapidly on {{ $labels.instance }}"
- alert: RedisConnectionsNearLimit
expr: redis_connected_clients / redis_config_maxclients > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "Redis connected clients above 80% of maxclients"Dragonfly en KeyDB: Redis-compatibele alternatieven
Hoewel Redis de dominante gegevensopslag in het geheugen is, hebben twee Redis-compatibele alternatieven aan populariteit gewonnen voor specifieke gebruiksscenario's.
Libel
Dragonfly is een moderne, multi-threaded Redis-vervanging die bedoeld is als drop-in-vervanging en tegelijkertijd gebruik maakt van alle beschikbare CPU-cores. Traditionele Redis is single-threaded voor opdrachtverwerking: Dragonfly gebruikt een architectuur zonder gedeelde gegevens met meerdere threads om een aanzienlijk hogere doorvoersnelheid te bereiken op multi-core machines. Het ondersteunt het Redis-protocol, de meeste Redis-opdrachten, en kan Redis vervangen zonder applicatiewijzigingen.
# Run Dragonfly as a Redis replacement
docker run -d --name dragonfly \
-p 6379:6379 \
-v /data/dragonfly:/data \
docker.dragonflydb.io/dragonflydb/dragonfly \
--maxmemory 12gb \
--proactor_threads 8 \
--dbfilename dump.rdb \
--requirepass strong_password
# Dragonfly in Kubernetes
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: dragonfly
namespace: production
spec:
replicas: 1
selector:
matchLabels:
app: dragonfly
template:
metadata:
labels:
app: dragonfly
spec:
containers:
- name: dragonfly
image: docker.dragonflydb.io/dragonflydb/dragonfly:latest
args:
- --maxmemory=12gb
- --proactor_threads=8
- --requirepass=strong_password
- --snapshot_cron=*/30 * * * *
ports:
- containerPort: 6379
resources:
requests:
cpu: "4"
memory: 16Gi
limits:
cpu: "8"
memory: 16Gi
volumeMounts:
- name: data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: longhorn
resources:
requests:
storage: 100GiDe belangrijkste voordelen vanDragonfly: multi-threaded (25x doorvoer op 8 cores versus single-threaded Redis), betere geheugenefficiëntie (gebruikt Dash-hashtabellen in plaats van Redis-dict), ingebouwde snapshotting zonder fork()-overhead en native ondersteuning voor grote datasets. Vanaf 2026 is de replicatieondersteuning van Dragonfly echter nog steeds in opkomst: het ondersteunt primaire replicareplicatie, maar beschikt nog niet over een Sentinel-equivalent automatisch failover-systeem. Gebruik voor HA Kubernetes-statuscontroles en StatefulSet-herstartbeleid, of implementeer achter een load balancer met failover op applicatieniveau.
KeyDB
KeyDB is een multi-threaded fork van Redis die wordt onderhouden door Snap (het bedrijf achter Snapchat). Het is volledig compatibel met Redis en voegt multi-threading, actief-actief replicatie (multi-master), FLASH-opslaglagen en het verlopen van subsleutels toe. De actief-actief-replicatie van KeyDB is vooral interessant voor HA: twee KeyDB-instanties kunnen tegelijkertijd schrijfbewerkingen accepteren en naar elkaar repliceren, waardoor een failover zonder downtime ontstaat.
# keydb.conf — Multi-threaded configuration with active replication
server-threads 4 # Use 4 threads for command processing
bind 0.0.0.0
port 6379
requirepass strong_password
masterauth strong_password
# Active-active replication (multi-master)
active-replica yes
replicaof peer-host 6379 # Bidirectional replication
# On the peer node, configure the reverse:
# replicaof this-host 6379
# FLASH storage tiering (for datasets larger than RAM)
# storage-provider flash /mnt/flash-storage 100
# maxmemory 16gb
# Will keep hot data in RAM and spill cold data to SSD
# SubKey expiration (unique to KeyDB)
# Allows setting TTL on hash fields, not just top-level keys
# EXPIREMEMBER myhash field1 3600KeyDB is een goede keuze wanneer u multi-master replicatie nodig heeft voor geografische distributie of onderhoud zonder downtime, of wanneer u een hogere doorvoer nodig heeft dan single-threaded Redis kan bieden, maar dichter bij de Redis-codebasis wilt blijven dan Dragonfly.
Prestatieafstemming
Pijpleidingen
Pipelining batches meerdere opdrachten in een enkele netwerkretour, waardoor de latentie voor bulkbewerkingen dramatisch wordt verminderd. In plaats van op elk antwoord te wachten voordat het volgende commando wordt verzonden, verzendt de client alle commando's in één keer en leest alle antwoorden samen.
# Python — Pipelining with redis-py
import redis
import time
r = redis.Redis(host='10.0.1.10', port=6379, password='password', decode_responses=True)
# Without pipelining: 1000 round-trips
start = time.time()
for i in range(1000):
r.set(f'key:{i}', f'value:{i}')
print(f'Without pipeline: {time.time() - start:.3f}s')
# With pipelining: 1 round-trip for 1000 commands
start = time.time()
pipe = r.pipeline(transaction=False)
for i in range(1000):
pipe.set(f'key:{i}', f'value:{i}')
pipe.execute()
print(f'With pipeline: {time.time() - start:.3f}s')
# Typically 5-10x fasterLua-scripting
Lua-scripts worden atomair uitgevoerd op de Redis-server, waardoor round-trips voor complexe bewerkingen worden geëlimineerd en wordt gegarandeerd dat er geen andere opdracht wordt uitgevoerd tussen de scriptbewerkingen. Zorg ervoor dat in Redis Cluster alle sleutels waartoe een Lua-script toegang heeft, zich in hetzelfde hash-slot bevinden met behulp van hash-tags.
# Lua script for atomic rate limiting
# KEYS[1] = rate limit key
# ARGV[1] = max requests
# ARGV[2] = window in seconds
local current = redis.call('INCR', KEYS[1])
if current == 1 then
redis.call('EXPIRE', KEYS[1], ARGV[2])
end
if current > tonumber(ARGV[1]) then
return 0 -- Rate limited
end
return 1 -- Allowed
# Load and execute
redis-cli -a password EVAL "\
local current = redis.call('INCR', KEYS[1]) \
if current == 1 then redis.call('EXPIRE', KEYS[1], ARGV[2]) end \
if current > tonumber(ARGV[1]) then return 0 end \
return 1" 1 ratelimit:user:123 100 60Geheugenoptimalisatie
# redis.conf — Memory optimisation settings
# Use ziplist encoding for small hashes, lists, sorted sets
hash-max-listpack-entries 128
hash-max-listpack-value 64
list-max-listpack-size -2 # 8KB per node
zset-max-listpack-entries 128
zset-max-listpack-value 64
set-max-intset-entries 512
# Lazy freeing (avoid blocking on large key deletion)
lazyfree-lazy-eviction yes
lazyfree-lazy-expire yes
lazyfree-lazy-server-del yes
lazyfree-lazy-user-del yes
lazyfree-lazy-user-flush yes
# jemalloc tuning
# MALLOC_CONF="background_thread:true,dirty_decay_ms:5000,muzzy_decay_ms:5000"
# Analyse memory usage
redis-cli -a password MEMORY DOCTOR
redis-cli -a password MEMORY STATS
redis-cli -a password --bigkeys
redis-cli -a password --memkeysVeel voorkomende foutscenario's en probleemoplossing voor
Scenario 1: Master mislukt, Sentinel promoot replica
# Diagnosis
redis-cli -p 26379 SENTINEL master mymaster
# Check: flags should show 's_down' or 'o_down' if master is unreachable
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
# Returns the current master address (should be the promoted replica)
# Check Sentinel logs for failover events
tail -f /var/log/redis/sentinel.log
# Look for: +sdown, +odown, +try-failover, +elected-leader,
# +failover-state-select-slave, +selected-slave,
# +failover-state-send-slaveof-noone, +failover-endScenario 2: Split-Brain met twee meesters
# Diagnosis: check if min-replicas-to-write is configured
redis-cli -a password CONFIG GET min-replicas-to-write
redis-cli -a password CONFIG GET min-replicas-max-lag
# Prevention: configure min-replicas on all masters
redis-cli -a password CONFIG SET min-replicas-to-write 1
redis-cli -a password CONFIG SET min-replicas-max-lag 10
# If split-brain occurred: identify the stale master
# Compare replication offsets — the master with the higher offset has more data
redis-cli -h master1-ip -a password INFO replication | grep master_repl_offset
redis-cli -h master2-ip -a password INFO replication | grep master_repl_offset
# Force the stale master to become a replica
redis-cli -h stale-master-ip -a password REPLICAOF correct-master-ip 6379Scenario 3: Volledige hersynchronisatie Storm na netwerkpartitie
# Diagnosis: check replication backlog
redis-cli -a password INFO replication | grep repl_backlog
# If repl_backlog_first_byte_offset is ahead of replica's offset, full sync triggers
# Prevention: increase backlog size
redis-cli -a password CONFIG SET repl-backlog-size 512mb
# Monitor for full syncs
redis-cli -a password INFO stats | grep sync_full
redis-cli -a password INFO stats | grep sync_partial_ok
redis-cli -a password INFO stats | grep sync_partial_errScenario 4: Geheugenuitputting en OOM Kill
# Diagnosis
redis-cli -a password INFO memory
# Check: used_memory vs maxmemory, mem_fragmentation_ratio
redis-cli -a password MEMORY DOCTOR
# Returns advice on memory issues
# Prevention: set proper maxmemory and eviction
redis-cli -a password CONFIG SET maxmemory 12gb
redis-cli -a password CONFIG SET maxmemory-policy allkeys-lru
# Find large keys consuming memory
redis-cli -a password --bigkeys
redis-cli -a password --memkeys --memkeys-samples 100
# Emergency: manually evict keys
redis-cli -a password SCAN 0 COUNT 1000 TYPE string
# Identify and DEL unnecessary large keysScenario 5: Langzame opdrachten blokkeren replicatie
# Diagnosis: check slowlog
redis-cli -a password SLOWLOG GET 20
redis-cli -a password SLOWLOG LEN
# Check for blocking commands
redis-cli -a password CLIENT LIST | grep -E 'cmd=(keys|sort|smembers)'
# Prevention: configure slowlog threshold
redis-cli -a password CONFIG SET slowlog-log-slower-than 10000 # 10ms
redis-cli -a password CONFIG SET slowlog-max-len 256
# Rename dangerous commands
rename-command KEYS "" # Disable KEYS entirely
rename-command FLUSHALL "" # Disable FLUSHALL
rename-command FLUSHDB "" # Disable FLUSHDB
rename-command DEBUG "" # Disable DEBUGCapaciteitsplanning en schaalstrategieën
Capaciteitsplanning voor Redis HA omvat het schatten van de geheugenvereisten, netwerkbandbreedte en CPU-gebruik over master- en replicanodes. De belangrijkste meetgegevens waarmee u rekening moet houden, zijn de grootte van de gegevensset, het aantal bewerkingen per seconde, de gemiddelde sleutel-/waardegrootte en de replicatieoverhead.
# Capacity estimation formulas
# Memory per node:
# Base dataset size (use redis-cli DBSIZE and MEMORY USAGE on a sample)
# + Replication output buffer: ~64MB per replica
# + AOF rewrite buffer: ~64MB during rewrites
# + Copy-on-write overhead during BGSAVE: up to 2x during heavy writes
# + Client output buffers: ~1KB per client
# + OS overhead: ~1-2GB
# Rule of thumb: maxmemory = 75% of available RAM
# Network bandwidth:
# Replication: write_throughput_bytes * num_replicas
# Client traffic: ops_per_sec * avg_response_size
# Full sync: dataset_size (one-time during replica bootstrap or failover)
# Example sizing for 20GB dataset, 100K ops/sec:
# RAM per node: 20GB data + 4GB buffers + 2GB OS = 26GB -> 32GB node (75% = 24GB maxmemory)
# CPU: 1 core handles ~100K ops/sec for simple commands (GET/SET)
# Network: 100K ops * 1KB avg = 100MB/s client + 50MB/s replication = 150MB/s per master
# Scaling decision tree:
# Need more read throughput? -> Add replicas (up to 5 per master)
# Need more write throughput? -> Redis Cluster (add shards)
# Need more memory? -> Redis Cluster (distribute dataset across shards)
# Need lower latency? -> Reduce network hops (co-locate, use unix sockets)
# Need global distribution? -> Multi-region replication or Redis Enterprise Active-ActiveHorizontaal schalen met Redis Cluster
# Add shards to an existing Redis Cluster
# 1. Start new Redis nodes
redis-server /etc/redis/new-master.conf
redis-server /etc/redis/new-replica.conf
# 2. Add the new master to the cluster
redis-cli --cluster add-node new-master:7000 existing-node:7000 -a password
# 3. Add the new replica to follow the new master
redis-cli --cluster add-node new-replica:7000 existing-node:7000 \
--cluster-slave --cluster-master-id NEW_MASTER_ID -a password
# 4. Reshard slots to the new master
redis-cli --cluster reshard existing-node:7000 \
--cluster-from all --cluster-to NEW_MASTER_ID \
--cluster-slots 4096 --cluster-yes -a password
# 5. Verify the new slot distribution
redis-cli -c -h existing-node -p 7000 -a password CLUSTER SLOTS
# Remove a shard (scale down)
# 1. Reshard all slots away from the node
redis-cli --cluster reshard existing-node:7000 \
--cluster-from REMOVING_NODE_ID --cluster-to TARGET_NODE_ID \
--cluster-slots 5461 --cluster-yes -a password
# 2. Remove the empty node
redis-cli --cluster del-node existing-node:7000 REMOVING_NODE_ID -a passwordOverwegingen bij verticale schaalvergroting
# When to scale vertically vs horizontally:
# Scale UP (bigger instances) when:
# - Dataset fits in single-node memory
# - Workload uses multi-key operations (MGET, SUNION, Lua across keys)
# - Operational simplicity is more important than cost efficiency
# - Using Redis modules that don't support Cluster mode well
# Scale OUT (more shards) when:
# - Dataset exceeds single-node memory
# - Write throughput exceeds single-thread capacity (~200K ops/sec)
# - You need per-shard isolation for multi-tenant workloads
# - Cost per GB of RAM is a concern (many smaller nodes vs few large ones)
# Cloud instance recommendations:
# AWS: cache.r7g.xlarge (4 vCPU, 26GB) to cache.r7g.16xlarge (64 vCPU, 419GB)
# Azure: P1 (6GB) to P5 (120GB) per shard
# GCP: 5GB to 300GB per instance (Memorystore Standard)
# Bare metal:
# CPU: 2-4 cores dedicated to Redis (single-threaded, but background tasks use extra cores)
# RAM: 32-128GB per node (NVMe for swap-as-last-resort)
# Network: 10Gbps minimum, 25Gbps for large datasets
# Storage: NVMe SSD for AOF/RDB persistence (IOPS matters for fsync)Conclusie
Redis hoge beschikbaarheid is geen enkele configuratiekeuze; het is een uitgebreid systeemontwerp dat replicatietopologie, foutdetectie, automatische failover, clientconfiguratie, persistentiestrategie, geheugenbeheer, beveiliging, monitoring en operationele procedures omvat. De juiste HA-architectuur hangt af van uw specifieke eisen.
Voor de meeste toepassingen biedtRedis Sentinelmet drie Sentinel-instances die een master en twee replica's bewaken, een beproefde, in de praktijk geteste HA-oplossing met automatische failover in minder dan 30 seconden. Wanneer u horizontale schaling nodig hebt die verder gaat dan de doorvoer- of geheugencapaciteit van een enkele master, verdeeltRedis Clusterde gegevensset over meerdere shards, terwijl de ingebouwde failover per shard behouden blijft. Voor Kubernetes-omgevingen coderen operators zoalsSpotahomeenOpsTreeoperationele best practices in declaratieve CRD's, terwijlRedis Enterprisede meest veelzijdige optie biedt met Active-Active geo-replicatie en module-ondersteuning.
Cloud-beheerde services –AWS ElastiCache,Azure Cache voor RedisenGCP Memorystore– elimineren de operationele lasten van het runnen van de Redis-infrastructuur, maar komen met verminderde flexibiliteit en hogere kosten op schaal. Voor organisaties met een bare metal-infrastructuur biedtk3s met Rancher en Longhorneen volledig open-source, cloud-onafhankelijk alternatief dat HA op bedrijfsniveau levert zonder leverancierlock-in.
Alternatieven zoalsDragonflyenKeyDBzijn het evalueren waard voor specifieke gebruiksscenario's: Dragonfly voor onbewerkte multi-threaded doorvoer op grote machines, en KeyDB voor actief-actieve multi-master replicatie. Beide zijn Redis-compatibel en kunnen in veel scenario's als drop-in vervanging dienen.
Ongeacht welke architectuur u kiest, de operationele fundamenten blijven constant: configureer de juiste persistentie (hybride RDB + AOF), dwingmin-replicas-to-writeaf om split-brain dataverlies te voorkomen, pas uw replicatieachterstand aan voor uw schrijfvolume, versleutel al het verkeer met TLS, dwing toegang met de minste bevoegdheden af met ACL's, bewaak replicatievertraging en geheugengebruik met Prometheus en Grafana, maak een back-up van RDB-snapshots naar duurzame externe opslag, en – het allerbelangrijkste – test uw failover regelmatig. Een failoversysteem dat nog nooit is getest, is een systeem dat niet werkt. Voer maandelijkse failover-oefeningen uit, injecteer fouten met chaos-engineeringtools en meet uw werkelijke hersteltijd. Het vertrouwen dat u krijgt door systematisch testen is wat een Redis-implementatie die productie-incidenten overleeft, onderscheidt van een implementatie die een serverstoring omzet in een bedrijfsbrede storing.