Linux Redis 运维实战:Redis Cluster 集群部署与管理
前言
Redis Cluster 是 Redis 提供的分布式解决方案,旨在满足大规模、高并发场景下的数据存储和高可用需求。相比主从复制和哨兵模式,Redis Cluster 通过数据分片和自动故障转移实现了更高的扩展性和可靠性。在 Linux 环境下,Redis Cluster 的部署与运维涉及多节点配置、槽分配、扩容缩容、监控告警和故障恢复等复杂任务。
一、Redis Cluster 原理
1.1 Redis Cluster 的工作机制
Redis Cluster 通过数据分片(sharding)将键空间划分为 16384 个槽(slot),由多个节点共同管理。其核心机制包括:
数据分片: 键通过 CRC16 算法映射到 0-16383 的槽。 每个节点负责一部分槽,数据分布在不同节点上。 节点通信: 节点通过 Gossip 协议交换状态信息,维护集群拓扑。 节点分为主节点(Master)和从节点(Slave),从节点为主节点提供备份。 故障转移: 主节点故障时,从节点自动升级为主节点,接管槽。 集群通过多数派(majority)机制确认故障。 客户端交互: 客户端通过集群协议(如 MOVED 重定向)访问正确节点。 支持智能客户端(如 JedisCluster、Lettuce)自动处理槽映射。
1.2 Redis Cluster 的特点
分布式存储:数据分片支持大规模数据存储。 高可用:主从节点自动故障转移。 线性扩展:支持动态添加或移除节点。 去中心化:无单点依赖,所有节点对等。
1.3 运维视角的挑战
部署复杂性:多节点配置和槽分配需精确规划。 数据一致性:故障转移和节点变更可能导致数据丢失。 性能优化:槽分布不均或热点键可能引发性能瓶颈。 监控需求:需实时监控槽状态、节点健康和集群一致性。
二、Redis Cluster 的部署与配置
2.1 环境准备
以下以 CentOS 8 为例,部署一个 6 节点(3 主 3 从)Redis Cluster:
节点信息:
主节点 1:192.168.1.100:6379 主节点 2:192.168.1.101:6379 主节点 3:192.168.1.102:6379 从节点 1:192.168.1.103:6379 从节点 2:192.168.1.104:6379 从节点 3:192.168.1.105:6379 前提:
Redis 7.0.12 已安装(参考专栏第 1 篇)。
防火墙允许 6379 和 16379(Gossip 协议端口):
sudo firewall-cmd --permanent --add-port={6379,16379}/tcp
sudo firewall-cmd --reload每节点磁盘空间 > 10GB,内存 > 4GB。
2.2 节点配置
为每个节点创建配置文件 etc/redis/redis.conf(以 192.168.1.100 为例):
bind 192.168.1.100
port 6379
requirepass your_secure_password
masterauth your_secure_password
dir var/redis/data/
logfile var/log/redis/redis.log
maxmemory 4gb
maxmemory-policy allkeys-lru
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
关键参数: cluster-enabled:启用集群模式。 cluster-config-file:存储集群拓扑信息,自动生成。 cluster-node-timeout:节点超时时间,影响故障检测速度。 requirepass 和 masterauth:设置密码,增强安全性。
其他节点配置类似,仅修改 bind 为对应 IP。启动所有节点:
sudo systemctl start redis
2.3 创建集群
使用 redis-cli 创建集群:
redis-cli --cluster create \
192.168.1.100:6379 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 \
--cluster-replicas 1 -a your_secure_password
参数说明: --cluster-replicas 1:每个主节点分配一个从节点。 -a:指定密码。 输出:确认槽分配(每个主节点约 5461 个槽)并同意创建。
2.4 验证集群
检查集群状态:
redis-cli -h 192.168.1.100 -p 6379 -a your_secure_password cluster info输出示例:
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_known_nodes:6查看节点信息:
redis-cli -h 192.168.1.100 -p 6379 -a your_secure_password cluster nodes输出示例:
node1 192.168.1.100:6379@16379 master - 0 1634567890 1 connected 0-5460
node2 192.168.1.101:6379@16379 master - 0 1634567890 2 connected 5461-10922
node3 192.168.1.102:6379@16379 master - 0 1634567890 3 connected 10923-16383
node4 192.168.1.103:6379@16379 slave node1 0 1634567890 4 connected
node5 192.168.1.104:6379@16379 slave node2 0 1634567890 5 connected
node6 192.168.1.105:6379@16379 slave node3 0 1634567890 6 connected测试数据存取:
redis-cli -c -h 192.168.1.100 -p 6379 -a your_secure_password
> SET key1 value1
> GET key1-c 启用集群模式,自动重定向到正确节点。
2.5 优化配置
节点超时:调整 cluster-node-timeout(如 10 秒)加速故障检测:
cluster-node-timeout 10000复制缓冲区:增大 repl-backlog-size 减少全量同步:
repl-backlog-size 50mb无盘复制:启用 repl-diskless-sync 优化高带宽场景:
repl-diskless-sync yes
三、集群扩展与缩容
3.1 扩展集群(添加节点)
添加新主节点(如 192.168.1.106:6379):
配置与现有节点一致,启动 Redis:
sudo systemctl start redis将新节点加入集群:
redis-cli --cluster add-node 192.168.1.106:6379 192.168.1.100:6379 -a your_secure_password重新分配槽:
使用 redis-cli --cluster reshard:
redis-cli --cluster reshard 192.168.1.100:6379 -a your_secure_password输入槽数量(如 4096,约 1/4 总槽数),选择源节点和新节点。
添加从节点(如 192.168.1.107:6379):
加入集群:
redis-cli --cluster add-node 192.168.1.107:6379 192.168.1.100:6379 -a your_secure_password设置为主节点的从节点:
redis-cli -h 192.168.1.107 -p 6379 -a your_secure_password CLUSTER REPLICATE <master-node-id>
3.2 缩容集群(移除节点)
移除从节点:
执行:
redis-cli --cluster del-node 192.168.1.107:6379 <node-id> -a your_secure_password移除主节点:
将槽迁移到其他主节点:
redis-cli --cluster reshard 192.168.1.100:6379 --cluster-from <node-id> --cluster-to <target-node-id> --cluster-slots 5461 -a your_secure_password删除节点:
redis-cli --cluster del-node 192.168.1.106:6379 <node-id> -a your_secure_password
3.3 运维实践
槽分配规划:确保槽均匀分布,避免单节点负载过高。 备份数据:扩容/缩容前备份 RDB 和 AOF 文件。 测试切换:模拟节点故障,验证槽迁移和数据一致性。
四、监控与告警
4.1 监控关键指标
使用 CLUSTER INFO 和 INFO 命令监控集群状态:
集群状态: cluster_state:ok 表示集群正常。 cluster_slots_assigned:已分配槽数(应为 16384)。 cluster_known_nodes:集群节点总数。 节点状态: role:主节点或从节点。 connected_slaves:主节点的从节点数。 repl_offset:复制偏移量。
4.2 Prometheus + Redis Exporter
部署 Redis Exporter:
docker run -d --name redis-exporter -p 9121:9121 oliver006/redis_exporter \
--redis.addr=redis://192.168.1.100:6379,redis://192.168.1.101:6379,redis://192.168.1.102:6379 \
--redis.password=your_secure_passwordPrometheus 配置:
scrape_configs:
- job_name: 'redis-cluster'
static_configs:
- targets: ['192.168.1.100:9121', '192.168.1.101:9121', '192.168.1.102:9121']关键指标:
redis_cluster_slots_assigned:已分配槽数。 redis_cluster_state:集群状态(1=ok,0=fail)。 redis_connected_slaves:从节点连接数。
4.3 告警规则
Prometheus 告警规则示例:
groups:
- name: redis-cluster
rules:
- alert: ClusterStateFail
expr: redis_cluster_state == 0
for: 5m
labels:
severity: critical
annotations:
summary: "Redis Cluster {{ $labels.instance }} state failed"
- alert: SlotUnassigned
expr: redis_cluster_slots_assigned < 16384
for: 5m
labels:
severity: warning
annotations:
summary: "Redis Cluster {{ $labels.instance }} has unassigned slots"
4.4 自动化监控脚本
Python 脚本示例:监控集群状态并发送告警。
import redis
import smtplib
from email.mime.text import MIMEText
r = redis.Redis(host='192.168.1.100', port=6379, password='your_secure_password')
info = r.cluster_info()
if info['cluster_state'] != 'ok':
msg = MIMEText(f'Redis Cluster state: {info["cluster_state"]}')
msg['Subject'] = 'Redis Cluster Alert'
msg['From'] = 'admin@example.com'
msg['To'] = 'ops@example.com'
with smtplib.SMTP('smtp.example.com') as smtp:
smtp.send_message(msg)运维实践:
定期运行脚本(如 cron 每 5 分钟)。 结合 Grafana 可视化槽分布和节点状态。
五、故障排查与恢复
5.1 常见故障及排查
集群状态异常(cluster_state: fail):
重新分配槽:
redis-cli --cluster fix 192.168.1.100:6379 -a your_secure_password重启故障节点。
检查 CLUSTER INFO 中的 cluster_slots_assigned。 查看节点日志:/var/log/redis/redis.log。 原因:槽未全部分配、节点宕机。
排查:
解决:
节点故障:
若主节点故障,等待从节点自动升级。
若从节点故障,重新加入集群:
redis-cli -h 192.168.1.103 -p 6379 -a your_secure_password CLUSTER REPLICATE <master-node-id>检查 CLUSTER NODES 的节点状态(fail 标志)。 验证复制偏移量:INFO REPLICATION。 原因:主节点宕机、从节点同步失败。
排查:
解决:
客户端重定向错误:
原因:客户端未正确处理 MOVED 或 ASK 重定向。 排查:检查客户端日志,确认是否使用集群模式客户端。 解决:升级客户端为 JedisCluster 或 Lettuce。
5.2 故障恢复
主节点宕机:
等待从节点自动升级为主节点(CLUSTER NODES 确认)。
修复原主节点,加入集群作为从节点:
redis-cli -h 192.168.1.100 -p 6379 -a your_secure_password CLUSTER REPLICATE <new-master-node-id>槽迁移失败:
检查槽状态:CLUSTER SLOTS。
手动修复:
redis-cli --cluster fix 192.168.1.100:6379 -a your_secure_password运维实践:
定期备份集群配置文件(nodes-6379.conf)。 模拟节点故障,测试故障转移时间。
六、运维案例:集群优化与故障恢复
6.1 场景描述
某 Redis Cluster(6 节点,32GB 内存,Redis 7.0)在高峰期出现槽分配不均,部分主节点 QPS 达 100k/s,集群状态变为 fail,客户端请求失败率达 15%。
6.2 排查步骤
检查集群状态: CLUSTER INFO 显示 cluster_state: fail,cluster_slots_assigned: 16000。 CLUSTER SLOTS 发现主节点 192.168.1.100 分配 8000 槽,其他节点约 4000 槽。 分析日志: 主节点日志显示高负载,CPU 占用 95%。 从节点日志提示同步延迟达 10MB。 监控数据: Prometheus 显示 redis_cluster_slots_assigned 未达 16384。 redis_connected_slaves 正常,但热点键集中在主节点 192.168.1.100。
6.3 优化措施
重新分配槽:
执行:
redis-cli --cluster reshard 192.168.1.100:6379 --cluster-from 192.168.1.100:6379 --cluster-to 192.168.1.101:6379 --cluster-slots 2000 -a your_secure_password确保每主节点约 5461 槽。
优化热点键:
使用 redis-cli --hotkeys 识别热点键。 通过客户端分片(如 Twemproxy)分散热点键访问。 调整参数:
降低 cluster-node-timeout:
cluster-node-timeout 5000增大 repl-backlog-size:
repl-backlog-size 100mb增强监控:
配置 Prometheus 告警,监控 redis_cluster_state 和 redis_cluster_slots_assigned。 添加 Grafana 仪表盘,展示槽分布和节点负载。
6.4 优化结果
集群状态恢复 ok,槽分配均匀。 主节点 QPS 均衡至 50k/s,CPU 占用降至 70%。 客户端请求失败率降至 1%,系统稳定性增强。
七、总结与展望
本篇讲解了 Redis Cluster 的原理、部署步骤、扩展缩容、监控与告警、故障排查与恢复实践。Redis Cluster 通过数据分片和高可用设计满足了大规模场景需求,运维工程师需掌握槽管理、节点扩展和故障处理技巧。




