Kubernetes 部署 Redis 集群
Redis 集群是一种分布式缓存解决方案,支持数据分片和高可用。在 Kubernetes 环境中可以使用 Redis Cluster 或 Sentinel 模式实现高可用架构。本文详细介绍两种方案的部署配置。
架构介绍
Redis Sentinel 模式
Redis Sentinel 是 Redis 官方提供的高可用解决方案,通过 sentinel 进程监控主节点状态,自动进行故障转移。Sentinel 模式适合对数据安全性要求较高的场景。
架构特点:主节点故障时自动选举从节点为新主节点;客户端通过 Sentinel 获取当前主节点地址;支持故障自动转移和服务发现;最少需要 3 个 Sentinel 实例保证高可用。
Redis Cluster 模式
Redis Cluster 是 Redis 官方提供的分布式解决方案,通过_slot 分片实现数据分布存储。Cluster 模式适合需要横向扩展的大规模缓存场景。
架构特点:数据自动分片到 16384 个 slot;每个分片可以有主从复制;支持自动故障转移和负载均衡;最少需要 6 个节点(3 主 3 从)。
架构选择建议
选择 Sentinel 模式的场景:需要完整的 ACID 事务支持;数据量较小但需要高可用;需要单实例透明访问。
选择 Cluster 模式的场景:数据量超过单节点内存容量;需要横向扩展能力;对性能要求极高。
部署资源清单(Redis Sentinel 模式)
1. 命名空间和 ServiceAccount
apiVersion: v1
kind: Namespace
metadata:
name: redis-cluster
labels:
name: redis-cluster
environment: production
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: redis
namespace: redis-cluster2. ConfigMap 配置
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
namespace: redis-cluster
data:
redis.conf: |
# 基础配置
bind: 0.0.0.0
port: 6379
protected-mode: no
timeout: 0
tcp-keepalive: 300
# 持久化配置
save: 900 1
save: 300 10
save: 60 10000
stop-writes-on-bgsave-error: yes
rdbcompression: yes
rdbchecksum: yes
dbfilename: dump.rdb
dir: /data
# 内存配置
maxmemory: 2gb
maxmemory-policy: allkeys-lru
maxmemory-samples: 5
# 复制配置
repl-diskless-sync: yes
repl-diskless-sync-delay: 5
repl-disable-tcp-nodelay: no
# 安全配置
requirepass: Redis@2024
masterauth: Redis@2024
# 日志配置
logfile: ""
syslog-enabled: no
# 性能优化
lazyfree-lazy-eviction: yes
lazyfree-lazy-expire: yes
lazyfree-lazy-server-del: yes
replica-lazy-flush: yes
# 客户端配置
timeout: 0
tcp-keepalive: 300
maxclients: 10000
sentinel.conf: |
port: 26379
sentinel announce-ip: 0.0.0.0
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel auth-pass mymaster Redis@20243. Headless Service
apiVersion: v1
kind: Service
metadata:
name: redis-headless
namespace: redis-cluster
labels:
app: redis
spec:
clusterIP: None
ports:
- name: redis
port: 6379
- name: sentinel
port: 26379
selector:
app: redis4. Redis Master StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-master
namespace: redis-cluster
spec:
serviceName: redis-headless
replicas: 3
selector:
matchLabels:
app: redis
role: master
template:
metadata:
labels:
app: redis
role: master
spec:
terminationGracePeriodSeconds: 10
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: redis
topologyKey: kubernetes.io/hostname
containers:
- name: redis
image: redis:7.2.4-alpine
imagePullPolicy: IfNotPresent
command:
- redis-server
- /usr/local/etc/redis/redis.conf
- --requirepass
- Redis@2024
- --masterauth
- Redis@2024
ports:
- name: redis
containerPort: 6379
resources:
requests:
cpu: 100m
memory: 512Mi
limits:
cpu: 2000m
memory: 4Gi
volumeMounts:
- name: data
mountPath: /data
- name: config
mountPath: /usr/local/etc/redis
livenessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: data
persistentVolumeClaim:
claimName: redis-data
- name: config
configMap:
name: redis-config
items:
- key: redis.conf
path: redis.conf
volumeClaimTemplates:
- metadata:
name: redis-data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: fast
resources:
requests:
storage: 10Gi5. Redis Replica StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-replica
namespace: redis-cluster
spec:
serviceName: redis-headless
replicas: 3
selector:
matchLabels:
app: redis
role: replica
template:
metadata:
labels:
app: redis
role: replica
spec:
terminationGracePeriodSeconds: 10
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: redis
topologyKey: kubernetes.io/hostname
containers:
- name: redis
image: redis:7.2.4-alpine
imagePullPolicy: IfNotPresent
command:
- redis-server
- /usr/local/etc/redis/redis.conf
- --replicaof
- 127.0.0.1
- 6379
- --requirepass
- Redis@2024
- --masterauth
- Redis@2024
ports:
- name: redis
containerPort: 6379
resources:
requests:
cpu: 100m
memory: 512Mi
limits:
cpu: 1000m
memory: 2Gi
volumeMounts:
- name: data
mountPath: /data
- name: config
mountPath: /usr/local/etc/redis
volumes:
- name: data
persistentVolumeClaim:
claimName: redis-replica-data
- name: config
configMap:
name: redis-config
items:
- key: redis.conf
path: redis.conf
volumeClaimTemplates:
- metadata:
name: redis-replica-data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: fast
resources:
requests:
storage: 10Gi6. Redis Services
apiVersion: v1
kind: Service
metadata:
name: redis-master-svc
namespace: redis-cluster
spec:
type: ClusterIP
ports:
- name: redis
port: 6379
targetPort: 6379
selector:
app: redis
role: master
---
apiVersion: v1
kind: Service
metadata:
name: redis-replica-svc
namespace: redis-cluster
spec:
type: ClusterIP
ports:
- name: redis
port: 6379
targetPort: 6379
selector:
app: redis
role: replica7. Redis Cluster 模式配置(可选)
如果选择 Redis Cluster 模式,使用以下 StatefulSet 配置:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-cluster
namespace: redis-cluster
spec:
serviceName: redis-cluster
replicas: 6
selector:
matchLabels:
app: redis-cluster
template:
metadata:
labels:
app: redis-cluster
spec:
terminationGracePeriodSeconds: 30
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: redis-cluster
topologyKey: kubernetes.io/hostname
containers:
- name: redis
image: redis:7.2.4-alpine
imagePullPolicy: IfNotPresent
command:
- redis-server
- /usr/local/etc/redis/redis.conf
- --cluster-enabled
- yes
- --cluster-config-file
- /data/nodes.conf
- --cluster-node-timeout
- 5000
ports:
- name: redis
containerPort: 6379
resources:
requests:
cpu: 100m
memory: 512Mi
limits:
cpu: 2000m
memory: 4Gi
volumeMounts:
- name: data
mountPath: /data
- name: config
mountPath: /usr/local/etc/redis
livenessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: data
emptyDir: {}
- name: config
configMap:
name: redis-config
items:
- key: redis.conf
path: redis.conf8. StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
allowVolumeExpansion: true
reclaimPolicy: Retain集群初始化(Cluster 模式)
Redis Cluster 初始化脚本
apiVersion: batch/v1
kind: Job
metadata:
name: redis-cluster-init
namespace: redis-cluster
spec:
template:
metadata:
labels:
app: redis-cluster-init
spec:
restartPolicy: OnFailure
containers:
- name: init
image: redis:7.2.4-alpine
command:
- sh
- -c
- |
#!/bin/bash
set -e
# 等待所有 Redis 节点就绪
echo "Waiting for Redis nodes..."
for i in 0 1 2 3 4 5; do
host="redis-cluster-$i.redis-cluster"
until redis-cli -h $host ping; do
echo "Waiting for $host..."
sleep 2
done
done
# 创建集群
redis-cli --cluster create \
redis-cluster-0.redis-cluster:6379 \
redis-cluster-1.redis-cluster:6379 \
redis-cluster-2.redis-cluster:6379 \
redis-cluster-3.redis-cluster:6379 \
redis-cluster-4.redis-cluster:6379 \
redis-cluster-5.redis-cluster:6379 \
--cluster-replicas 1 \
--cluster-yes \
--pass Redis@2024
echo "Redis Cluster initialized successfully"
env:
- name: REDIS_PASSWORD
value: "Redis@2024"部署步骤
1. 创建命名空间和配置
kubectl apply -f 00-namespace.yaml
kubectl apply -f 01-configmap.yaml
kubectl apply -f 02-storageclass.yaml2. 创建 Service
kubectl apply -f 03-services.yaml3. 创建 StatefulSet
# Sentinel 模式
kubectl apply -f 04-redis-master.yaml
kubectl apply -f 05-redis-replica.yaml
# Cluster 模式
kubectl apply -f 04-redis-cluster.yaml
kubectl apply -f 06-cluster-init-job.yaml4. 验证部署
# 查看 Pod 状态
kubectl get pods -n redis-cluster
# 查看服务
kubectl get svc -n redis-cluster
# 验证 Redis 连接
kubectl exec -it redis-master-0 -n redis-cluster -- redis-cli -a Redis@2024 ping
# 查看集群状态(Cluster 模式)
kubectl exec -it redis-cluster-0 -n redis-cluster -- redis-cli -a Redis@2024 cluster info应用配置示例
Java 应用配置
// Jedis 配置
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(20);
poolConfig.setMaxIdle(10);
poolConfig.setMinIdle(5);
JedisPool jedisPool = new JedisPool(poolConfig,
"redis-master-svc.redis-cluster.svc.cluster.local",
6379,
2000,
"Redis@2024");
// Spring Boot 配置
spring:
redis:
host: redis-master-svc.redis-cluster.svc.cluster.local
password: Redis@2024
port: 6379
lettuce:
pool:
max-active: 20
max-idle: 10
min-idle: 5Python 应用配置
import redis
# Sentinel 模式
from redis.sentinel import Sentinel
sentinel = Sentinel([
('redis-sentinel-0.redis-cluster.svc.cluster.local', 26379),
('redis-sentinel-1.redis-cluster.svc.cluster.local', 26379),
('redis-sentinel-2.redis-cluster.svc.cluster.local', 26379)
], sentinel_kwargs={'password': 'Redis@2024'})
master = sentinel.master_for('mymaster', password='Redis@2024')
# Cluster 模式
cluster = redis.Cluster(
nodes=[
'redis-cluster-0.redis-cluster:6379',
'redis-cluster-1.redis-cluster:6379',
],
password='Redis@2024'
)监控和告警
Prometheus Exporter 配置
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-monitoring
namespace: redis-cluster
data:
redis-exporter.yaml: |
- job_name: redis_exporter
static_configs:
- targets:
- redis-master-0.redis-cluster:9121
- redis-master-1.redis-cluster:9121
- redis-master-2.redis-cluster:9121告警规则
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: redis-alerts
namespace: redis-cluster
spec:
groups:
- name: redis.rules
rules:
- alert: RedisDown
expr: up{job="redis_exporter"} == 0
for: 2m
labels:
severity: critical
- alert: RedisMemoryHigh
expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.9
for: 5m
labels:
severity: warning
- alert: RedisReplicationLag
expr: redis_replication_seconds_since_source_repl > 30
for: 5m
labels:
severity: warning运维操作
备份和恢复
# 备份(RDB 快照)
kubectl exec redis-master-0 -n redis-cluster -- \
redis-cli -a Redis@2024 SAVE
# 恢复
kubectl cp dump.rdb redis-master-0:/data/dump.rdb -n redis-cluster
kubectl exec redis-master-0 -n redis-cluster -- \
redis-cli -a Redis@2024 DEBUG RELOAD扩缩容
# 扩容副本
kubectl scale statefulset redis-replica -n redis-cluster --replicas=5
# 手动故障转移
kubectl exec redis-replica-0 -n redis-cluster -- \
redis-cli -a Redis@2024 REPLICAOF NO ONE常见问题排查
连接失败
检查安全组规则和网络策略;验证密码配置是否正确;检查服务发现配置。
复制延迟
优化慢查询;增加网络带宽;调整 repl-diskless-sync 配置。
内存不足
调整 maxmemory 配置;选择合适的淘汰策略;增加节点资源。
总结
本文提供了在 Kubernetes 环境中部署 Redis Sentinel 集群和 Redis Cluster 集群的完整方案。生产环境中建议配合使用监控告警系统,定期检查集群状态,并设置合理的备份策略。根据业务数据量和可用性要求选择合适的部署模式。
