Redis Cluster是Redis的分布式方案,通过16384个哈希槽分片数据,支持高可用与自动故障转移,基于Gossip协议通信,客户端通过MOVED/ASK重定向访问,适用于大规模场景。
Redis Cluster 是 Redis 官方提供的分布式解决方案,支持 数据分片、高可用 和 自动故障转移。它通过将数据分散到多个节点,突破单机内存与性能限制,适用于大规模数据场景。
一、核心概念与架构
1. 数据分布
-
哈希槽(Hash Slot) : Redis Cluster 将数据划分为 16384 个槽,每个键通过 CRC16 算法计算哈希值,再取模映射到具体槽:
slot = CRC16(key) % 16384 -
槽分配: 每个主节点负责一部分槽(如 Node1 负责 0-5000,Node2 负责 5001-10000 等)。
# 查看槽分配 CLUSTER SLOTS
2. 节点角色
- 主节点(Master) :负责处理读写请求及槽管理。
- 从节点(Replica) :复制主节点数据,主节点故障时替代为主节点。
3. 高可用
- 每个主节点至少有一个从节点(推荐一主一从)。
- 主节点故障时,从节点自动升级为新主节点。
二、搭建 Redis Cluster
1. 最小集群配置(6节点:3主3从)
-
节点配置: 每个节点的
redis.conf中启用集群模式:port 7000 cluster-enabled yes cluster-config-file nodes-7000.conf cluster-node-timeout 5000 -
启动节点:
redis-server redis-7000.conf # 重复启动 7001~7005 节点 -
创建集群: 使用
redis-cli自动分配槽:redis-cli --cluster create \ 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \ 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \ --cluster-replicas 1 -
验证集群状态:
redis-cli -p 7000 CLUSTER INFO redis-cli -p 7000 CLUSTER NODES
三、节点通信与请求路由
1. Gossip 协议
- 节点间通过 PING/PONG 消息交换状态(节点存活、槽分配等)。
- 每个节点维护全量节点元数据,每秒随机选择部分节点通信。
2. 客户端路由
-
MOVED 重定向:客户端访问错误槽时,返回正确节点地址。
GET key # 返回 MOVED 1234 127.0.0.1:7001 -
ASK 重定向:槽迁移期间临时重定向到目标节点。
-
Smart Client:客户端缓存槽与节点映射,直接访问正确节点。
四、故障转移与恢复
1. 故障检测
- 节点间通过心跳检测状态,若主节点超时(
cluster-node-timeout),标记为 PFail(可能下线) 。 - 多数主节点确认后,标记为 Fail(确认下线) 。
2. 从节点晋升
- 从节点发起选举(基于 Raft 协议),获得多数主节点投票后升级为主节点。
- 更新集群元数据,同步新主节点信息。
五、扩容与缩容
1. 扩容流程
-
添加新节点:
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 -
分配槽:
redis-cli --cluster reshard 127.0.0.1:7000 # 输入迁移槽数量及目标节点ID -
添加从节点:
redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7000 --cluster-slave --cluster-master-id <master-id>
2. 缩容流程
-
迁移槽:将待删除节点的槽迁移到其他节点。
-
删除节点:
redis-cli --cluster del-node 127.0.0.1:7000 <node-id>
六、客户端实现
1. Smart Client 逻辑
- 初始化时获取集群槽分布(
CLUSTER SLOTS)。 - 计算 Key 的槽并缓存槽-节点映射。
- 遇到
MOVED错误时更新缓存。
2. 示例(Python redis-py-cluster)
from rediscluster import RedisCluster
startup_nodes = [{"host": "127.0.0.1", "port": "7000"}]
rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)
rc.set("key", "value")
print(rc.get("key")) # 输出 "value"
七、优缺点分析
| 优点 | 缺点 |
|---|---|
| 自动分片,支持水平扩展 | 不支持多数据库(仅 DB0) |
| 内置高可用,故障自动转移 | 跨槽事务受限(需所有 Key 在同一槽) |
| 无中心节点,去中心化架构 | 批量操作需确保 Key 在同一槽(如 MGET) |
| 兼容大部分 Redis 命令 | 集群规模过大时 Gossip 通信开销增加 |
八、运维实践
1. 监控与告警
-
关键指标:
- 节点状态:
cluster_state、cluster_slots_assigned。 - 内存与延迟:
used_memory、latency。
- 节点状态:
-
工具:
redis-cli --cluster check:检查集群健康状态。- Prometheus + Grafana:监控集群指标。
2. 数据备份
- RDB 备份:在每个节点配置
save或手动执行BGSAVE。 - AOF 备份:启用
appendonly yes,定期备份 AOF 文件。
3. 热点 Key 处理
- 拆分 Key:将热点 Key 分片到多个槽(如
user:{1000}:profile→user:1000:profile_{1,2,3})。 - 本地缓存:客户端缓存热点数据,减少集群压力。
4. 安全配置
-
密码认证:所有节点配置
requirepass和masterauth。 -
禁用危险命令:
rename-command FLUSHDB "" rename-command CONFIG "HIDDEN_CONFIG"
九、常见问题与解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 集群节点无法启动 | 端口冲突或配置文件错误 | 检查端口占用,验证配置文件 |
| 槽未完全分配 | 节点未正确加入集群 | 使用 redis-cli --cluster fix 修复 |
| 客户端频繁 MOVED 重定向 | 槽映射缓存未更新 | 客户端实现自动重试与缓存刷新 |
| 网络分区导致脑裂 | 主节点间通信中断 | 配置 cluster-require-full-coverage no 允许部分写入 |
总结
Redis Cluster 是构建大规模、高可用 Redis 服务的核心方案,适用于以下场景:
- 数据量超过单机内存容量。
- 需要高可用与自动故障转移。
- 业务允许跨槽操作限制(如事务、Lua 脚本)。
通过合理设计分片策略、监控集群状态,并遵循最佳实践,可充分发挥 Redis Cluster 的优势。