Skip to content

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 版本:

text
                    +----------------------+
                    | 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:

text
slot = CRC16(key) % 16384

如果 key 中包含 hash tag,只有 {} 内的内容参与 slot 计算:

text
user:{1001}:profile
user:{1001}:orders

这两个 key 会落到同一个 slot,适合需要多 key 操作的场景。

副本反亲和

不要把某个 master 和它的 replica 放在同一台机器上。推荐交叉放置:

机器主节点从节点
节点 1Master-1Replica-3
节点 2Master-2Replica-1
节点 3Master-3Replica-2

这样任意一台机器故障时,剩余机器上仍有对应副本可以提升为 master。

故障转移

当某个 master 不可达时,集群内其他 master 会通过投票确认故障。该 master 的 replica 获得多数 master 投票后提升为新的 master,并接管原 slot 范围。

故障转移链路:

部署配置要点

每个 Redis 实例需要开启 cluster 模式:

text
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-enabledyes开启 Redis Cluster
cluster-node-timeout5000 起步节点不可达判定时间,过短容易误判
appendonlyyes开启 AOF,降低故障后的数据丢失窗口
appendfsynceverysec性能和可靠性折中
protected-mode生产按网络边界配置不要直接暴露到公网

创建 3 主 3 从集群:

bash
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.116379638016379 / 16380
10.0.0.126379638016379 / 16380
10.0.0.136379638016379 / 16380

目录规划

每个 Redis 实例使用独立目录,避免 nodes.conf、AOF、RDB 文件互相覆盖:

text
/data/redis-cluster/
├── 6379/
│   ├── redis.conf
│   ├── data/
│   └── logs/
└── 6380/
    ├── redis.conf
    ├── data/
    └── logs/

创建目录:

bash
sudo mkdir -p /data/redis-cluster/{6379,6380}/{data,logs}
sudo chown -R redis:redis /data/redis-cluster

配置实例

6379/redis.conf

text
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 everysec

6380/redis.conf 只需要替换端口、目录和文件名:

text
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

启动实例

bash
redis-server /data/redis-cluster/6379/redis.conf
redis-server /data/redis-cluster/6380/redis.conf

检查端口:

bash
redis-cli -h 10.0.0.11 -p 6379 PING
redis-cli -h 10.0.0.11 -p 6380 PING

创建集群

在任意一台机器执行:

bash
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。

验证集群

查看集群状态:

bash
redis-cli -c -h 10.0.0.11 -p 6379 CLUSTER INFO

关键字段:

text
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_known_nodes:6
cluster_size:3

查看节点拓扑:

bash
redis-cli -c -h 10.0.0.11 -p 6379 CLUSTER NODES

写入测试:

bash
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:

bash
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:

bash
redis-cli --cluster add-node \
  10.0.0.14:6380 10.0.0.11:6379 \
  --cluster-slave \
  --cluster-master-id <master-node-id>

扩容后再次执行 CLUSTER INFOCLUSTER NODES,确认 slot 覆盖完整、主从关系符合机器反亲和。

生产检查清单

  • 客户端必须使用支持 Redis Cluster 的连接库,不能只连单个固定节点。
  • 防火墙同时放通 Redis 服务端口和 cluster bus 端口。
  • master 与 replica 跨机器、跨可用区放置,避免单点机器故障导致主从同时丢失。
  • 开启持久化,明确 RDB / AOF 的恢复策略和磁盘容量预警。
  • 监控 cluster_statecluster_slots_ok、主从复制延迟、内存使用率、慢查询和淘汰 key 数量。
  • 避免跨 slot 的多 key 命令;确实需要时使用 hash tag 控制 key 落到同一 slot。
  • 预留扩容路径,新增 master 后通过 slot 迁移完成数据再平衡。