Redis 集群
架构 + 原理 + 分片 + 选主 + 读写 + 运维 + 最佳实践
Redis Cluster 是 Redis 官方原生的 分布式集群方案,用于实现:
- 数据分片(水平扩容)
- 高可用(自动故障转移)
- 强一致性 hash slot 路由
- 内置主从复制
目标:在多节点间共享数据,扩展读性能、写性能,避免单机内存与带宽瓶颈。
┌─────────┐
┌──► │ Master1│ ◄──┐
│ └─────────┘ │
│ ▲ ▲ │
│ │ │ │
│ Slave1 Slave2 │
│ │
Client ─┼───────────────────┼- Cluster Bus
│ │
│ ┌─────────┐ │
└──► │ Master2 │ ◄──┘
└─────────┘
▲
Slave3
关键特征:
- 每个主节点管理一部分 Hash Slot
- 每个主节点至少 1 个从节点(推荐)
- 客户端直连任意节点,节点返回数据或 MOVED 跳转
- 节点之间通过 Cluster Bus(端口+10000) 通信
Redis Cluster 将整个数据库划分为:
16384 个槽位(slot)
每个 key 通过 CRC16 算法取模:
slot = CRC16(key) % 16384
每个主节点负责一部分 slot,例如:
Master1 -> 0 ~ 5460
Master2 -> 5461 ~ 10922
Master3 -> 10923 ~ 16383
你可以通过 {tag} 固定 key 的 slot:
例如:
user:{1001}:info
user:{1001}:like
user:{1001}:follow
三个 key 都会落在同一个 slot -> 可以执行 MULTI 命令、Lua、pipeline
非常重要!
客户端可以连接任意节点。
写流程:
Client -> NodeA
if NodeA 负责该 slot:
写成功
else:
NodeA 返回 MOVED (slot, rightNode)
Client 自动重定向到 rightNode
- 该 slot 未来都由这个新节点负责
- -> 正式迁移已完成
- -> 客户端应该更新自己的 slot 缓存
- 该 slot 正在迁移中
- -> 临时性的
- -> 客户端向旧节点 ASKING,然后访问新节点
Redis 采用 Gossip 协议(基于 cluster bus)感知节点状态。
节点的状态:
- PFAIL:某个节点认为另外一个节点挂了(主观宕机)
- FAIL:半数以上 master 认为某节点挂了 -> 客观宕机
当某个 Master 宕机:
-
它的从节点中会选举一个作为新的 Master
-
选举条件:
- 与主节点断联时间在 10 秒以内(cluster-node-timeout)
- 复制 offset 位置靠前(数据最全)
-
其他节点进行投票,过半即可成为新主
Redis Cluster 属于:
AP(高可用高性能)+ 弱一致性
原因:
- 集群不支持 multi-key 跨 slot 的事务
- Cluster 在多数节点存活时继续服务
- 网络分区可能导致短暂不一致
官方推荐:
3 主 3 从(共 6 节点)
更大部署:
6 主 6 从(12 节点)
9 主 9 从(18 节点)
内存规划:
- 每个节点不超过 50GB 内存(过大会导致 RDB/AOF 巨大)
- 单 slot 持有的 key 尽量均衡
查看集群节点
cluster nodes
查看 slot 分布
cluster slots
调整分片(slot 迁移)
redis-cli --cluster reshard ...
创建集群
redis-cli --cluster create host1:7000 host2:7001 ... --cluster-replicas 1
如:
- Python:redis-py cluster
- Go:go-redis cluster
- Java:lettuce / Redisson(最推荐)
普通 redis 客户端无法使用 cluster。
否则:
- 迁移 slot 时非常慢
- 会导致阻塞、延迟增加
需要用 Lua 或者分布式锁进行补充。
除非 key 使用 hash tag:
order:{1001}:base
order:{1001}:items
order:{1001}:price
解决:
- 用 Redisson 保证强制读主节点
- 或等同步 offset 确认后再读
- used_memory
- mem_fragmentation_ratio
- latency spikes
- slowlog
- slave_repl_offset
- master_repl_offset
- connected_clients
- 各节点 key 和 slot 是否平衡
| 功能 | Redis Cluster | Sentinel 集群 |
|---|---|---|
| 数据分片 | ✅ | ❌ |
| 自动分片(扩容) | ✅ | ❌ |
| 高可用 | ✅ | ✅ |
| 部署复杂度 | 高 | 中 |
| 客户端要求 | 要支持 cluster | 普通客户端即可 |
| 多 key 事务 | 部分支持 | 完全支持 |
结论:需要扩容选 Cluster,传统业务选 Sentinel。
6 节点(3 主 3 从)
至少两个机房(分 AZ)
为了避免 RDB/AOF 生成过慢
这样 slot 迁移才会快、复制不会阻塞。
提高业务的聚合性、减少跨 slot。
原因:
- 某个 master 节点挂了
- 所有从节点也挂了
- 或者 slot 迁移未完成
解决:
- 检查节点
- 重建从节点
- 重新挂载 slot
原因:
- 存在大 key
- 网络瓶颈
解决:
- 先扫描大 key -> 拆分
- 调整 migrate 参数(pipeline)
原因:
- 主节点压力过大
- 网络不稳定
- 大 key 同步
解决:
- 优化慢命令
- 调整节点负载
- 避免大 key