Redis 集群部署架构
Redis 的高可用部署通常分为两类:
- 主从复制 + Sentinel:适合单主写入、容量不需要横向分片的场景,Sentinel 负责故障发现和主从切换。
- Redis Cluster:适合需要横向扩容的场景,数据按 slot 分片到多个 master,每个 master 配置 replica 承担高可用。
生产环境中,如果目标是同时获得分片扩容和自动故障转移,优先使用 Redis Cluster。
推荐拓扑:3 主 3 从
Redis Cluster 默认将 key 空间划分为 16384 个 hash slot。最小高可用拓扑通常是 3 个 master + 3 个 replica,每个 master 负责一段 slot,每个 replica 跟随一个不同机器上的 master。
同一拓扑的 ASCII 版本:
+----------------------+
| Redis Cluster Client |
| MOVED / ASK redirect |
+----------+-----------+
|
+----------------+----------------+
| | |
v v v
+--------------------+ +--------------------+ +--------------------+
| Node 1 | | Node 2 | | Node 3 |
| | | | | |
| Master-1 :6379 | | Master-2 :6379 | | Master-3 :6379 |
| slots 0-5460 | | slots 5461-10922 | | slots 10923-16383 |
| | | | | |
| Replica-3 :6380 | | Replica-1 :6380 | | Replica-2 :6380 |
| follows Master-3 | | follows Master-1 | | follows Master-2 |
+---------+----------+ +---------+----------+ +---------+----------+
| | |
| async replication | async replication | async replication
| | |
+--------------------->+ |
+--------------------->+
<---------------------------------------------+
Cluster bus:
Master-1:16379 <----> Master-2:16379 <----> Master-3:16379
^----------------------------------------------^组件职责
| 组件 | 职责 |
|---|---|
| Redis Cluster Client | 维护 slot 到节点的映射,处理 MOVED / ASK 重定向,避免应用层手动路由 |
| Master | 承担读写请求,负责一段 hash slot |
| Replica | 异步复制 master 数据,master 故障后参与选举并提升为新 master |
| Cluster Bus | 节点间通信通道,默认端口是服务端口 + 10000,例如 6379 对应 16379 |
关键设计点
分片规则
Redis Cluster 使用 CRC16 计算 key 所属 slot:
slot = CRC16(key) % 16384如果 key 中包含 hash tag,只有 {} 内的内容参与 slot 计算:
user:{1001}:profile
user:{1001}:orders这两个 key 会落到同一个 slot,适合需要多 key 操作的场景。
副本反亲和
不要把某个 master 和它的 replica 放在同一台机器上。推荐交叉放置:
| 机器 | 主节点 | 从节点 |
|---|---|---|
| 节点 1 | Master-1 | Replica-3 |
| 节点 2 | Master-2 | Replica-1 |
| 节点 3 | Master-3 | Replica-2 |
这样任意一台机器故障时,剩余机器上仍有对应副本可以提升为 master。
故障转移
当某个 master 不可达时,集群内其他 master 会通过投票确认故障。该 master 的 replica 获得多数 master 投票后提升为新的 master,并接管原 slot 范围。
故障转移链路:
部署配置要点
每个 Redis 实例需要开启 cluster 模式:
port 6379
bind 0.0.0.0
protected-mode no
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 5000
appendonly yes
appendfsync everysec关键参数:
| 参数 | 建议 | 说明 |
|---|---|---|
cluster-enabled | yes | 开启 Redis Cluster |
cluster-node-timeout | 5000 起步 | 节点不可达判定时间,过短容易误判 |
appendonly | yes | 开启 AOF,降低故障后的数据丢失窗口 |
appendfsync | everysec | 性能和可靠性折中 |
protected-mode | 生产按网络边界配置 | 不要直接暴露到公网 |
创建 3 主 3 从集群:
redis-cli --cluster create \
10.0.0.11:6379 10.0.0.12:6379 10.0.0.13:6379 \
10.0.0.11:6380 10.0.0.12:6380 10.0.0.13:6380 \
--cluster-replicas 1部署流程
下面以 3 台机器、每台 2 个 Redis 实例为例:
| 机器 | Master 实例 | Replica 实例 | Cluster Bus |
|---|---|---|---|
10.0.0.11 | 6379 | 6380 | 16379 / 16380 |
10.0.0.12 | 6379 | 6380 | 16379 / 16380 |
10.0.0.13 | 6379 | 6380 | 16379 / 16380 |
目录规划
每个 Redis 实例使用独立目录,避免 nodes.conf、AOF、RDB 文件互相覆盖:
/data/redis-cluster/
├── 6379/
│ ├── redis.conf
│ ├── data/
│ └── logs/
└── 6380/
├── redis.conf
├── data/
└── logs/创建目录:
sudo mkdir -p /data/redis-cluster/{6379,6380}/{data,logs}
sudo chown -R redis:redis /data/redis-cluster配置实例
6379/redis.conf:
port 6379
bind 0.0.0.0
protected-mode no
dir /data/redis-cluster/6379/data
logfile /data/redis-cluster/6379/logs/redis.log
pidfile /data/redis-cluster/6379/redis.pid
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 5000
appendonly yes
appendfilename appendonly-6379.aof
appendfsync everysec6380/redis.conf 只需要替换端口、目录和文件名:
port 6380
dir /data/redis-cluster/6380/data
logfile /data/redis-cluster/6380/logs/redis.log
pidfile /data/redis-cluster/6380/redis.pid
cluster-config-file nodes-6380.conf
appendfilename appendonly-6380.aof启动实例
redis-server /data/redis-cluster/6379/redis.conf
redis-server /data/redis-cluster/6380/redis.conf检查端口:
redis-cli -h 10.0.0.11 -p 6379 PING
redis-cli -h 10.0.0.11 -p 6380 PING创建集群
在任意一台机器执行:
redis-cli --cluster create \
10.0.0.11:6379 10.0.0.12:6379 10.0.0.13:6379 \
10.0.0.11:6380 10.0.0.12:6380 10.0.0.13:6380 \
--cluster-replicas 1--cluster-replicas 1 表示每个 master 分配 1 个 replica。创建完成后,Redis 会自动分配 slot 和主从关系;如果自动分配不满足反亲和要求,需要手动调整 replica 所属 master。
验证集群
查看集群状态:
redis-cli -c -h 10.0.0.11 -p 6379 CLUSTER INFO关键字段:
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_known_nodes:6
cluster_size:3查看节点拓扑:
redis-cli -c -h 10.0.0.11 -p 6379 CLUSTER NODES写入测试:
redis-cli -c -h 10.0.0.11 -p 6379 SET user:{1001}:name Henry
redis-cli -c -h 10.0.0.12 -p 6379 GET user:{1001}:name-c 会让 redis-cli 自动处理 MOVED / ASK 重定向,更接近应用客户端的访问方式。
扩容入口
新增 master 后需要迁移 slot:
redis-cli --cluster add-node 10.0.0.14:6379 10.0.0.11:6379
redis-cli --cluster reshard 10.0.0.11:6379新增 replica:
redis-cli --cluster add-node \
10.0.0.14:6380 10.0.0.11:6379 \
--cluster-slave \
--cluster-master-id <master-node-id>扩容后再次执行 CLUSTER INFO 和 CLUSTER NODES,确认 slot 覆盖完整、主从关系符合机器反亲和。
生产检查清单
- 客户端必须使用支持 Redis Cluster 的连接库,不能只连单个固定节点。
- 防火墙同时放通 Redis 服务端口和 cluster bus 端口。
- master 与 replica 跨机器、跨可用区放置,避免单点机器故障导致主从同时丢失。
- 开启持久化,明确 RDB / AOF 的恢复策略和磁盘容量预警。
- 监控
cluster_state、cluster_slots_ok、主从复制延迟、内存使用率、慢查询和淘汰 key 数量。 - 避免跨 slot 的多 key 命令;确实需要时使用 hash tag 控制 key 落到同一 slot。
- 预留扩容路径,新增 master 后通过 slot 迁移完成数据再平衡。