跳到主要内容

Redis Cluster:分片、扩缩容与恢复

Cluster 将 key 分到 16,384 个 slot:CRC16(key) mod 16384。它解决容量和写吞吐的横向扩展,但客户端必须支持 MOVED/ASK 重定向。

Sentinel 的全部数据仍在一个主节点;Cluster 则把不同 slot 放到不同主节点。业务尚未达到单机容量或写吞吐边界时,不应只为“看起来高可用”而增加 Cluster 运维复杂度。

1. 用例子理解 Hash Slot

在 Cluster 节点执行:

redis-cli -c -h 10.0.20.11 CLUSTER KEYSLOT 'user:42'
redis-cli -c -h 10.0.20.11 CLUSTER KEYSLOT 'order:1001'
redis-cli -c -h 10.0.20.11 CLUSTER KEYSLOT '{order:1001}:detail'
redis-cli -c -h 10.0.20.11 CLUSTER KEYSLOT '{order:1001}:items'

最后两个 key 的花括号内容相同,因此位于同一 slot,可参与需要同 slot 的多 key 命令。不要让所有 key 使用同一个 hash tag,否则会形成热点主节点。

2. 规划三主三从

master-1 slots 0-5460 → replica-1
master-2 slots 5461-10922 → replica-2
master-3 slots 10923-16383 → replica-3

主节点和自己的副本要跨主机/可用区。节点需互通服务端口和 Cluster bus 端口,bus 默认是服务端口加 10000,例如 6379 对应 16379。

关键配置:

cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

nodes.conf 由 Redis 自动维护,每个节点必须使用独立文件和数据目录,不能让多个实例共享。

3. 创建并验证集群

确保六个空节点已经启动:

redis-cli --cluster create \
10.0.20.11:6379 10.0.20.12:6379 10.0.20.13:6379 \
10.0.20.21:6379 10.0.20.22:6379 10.0.20.23:6379 \
--cluster-replicas 1

命令会显示 slot 和副本分配计划。确认前检查副本是否真的与主节点跨故障域。

redis-cli -c -h 10.0.20.11 CLUSTER INFO
redis-cli -c -h 10.0.20.11 CLUSTER NODES
redis-cli --cluster check 10.0.20.11:6379

基本健康条件包括:cluster_state:okcluster_slots_assigned:16384cluster_slots_fail:0,并且每个主节点有 slot、每个副本指向预期主节点。

4. MOVED 与 ASK

  • MOVED:slot 已稳定归属另一个节点,客户端应更新 slot 缓存;
  • ASK:slot 正在迁移,本次临时请求另一个节点,不能永久更新映射。

redis-cli -c 会自动跟随重定向。应用必须使用 Cluster 客户端;普通单机客户端收到 MOVED 后报错不代表集群坏了。

5. 扩容:先加节点,再迁 slot

redis-cli --cluster add-node 10.0.20.14:6379 10.0.20.11:6379
redis-cli --cluster reshard 10.0.20.11:6379
redis-cli --cluster check 10.0.20.11:6379

新主节点加入后没有 slot,因此不会保存业务数据。reshard 时指定迁移 slot 数、来源节点和目标 node ID;迁移期间监控应用 P99 延迟、网络和 CPU。

添加副本时:

redis-cli --cluster add-node 10.0.20.24:6379 10.0.20.11:6379 \
--cluster-slave --cluster-master-id <master-node-id>

6. 缩容:先迁空,再删除

  1. 确认目标 node ID 和角色;
  2. 将主节点所有 slot 迁至其他主节点;
  3. --cluster check 确认 slot 完整;
  4. 重新分配或删除它的副本;
  5. 执行 del-node
  6. 检查应用错误率和 Cluster 状态。
redis-cli --cluster del-node 10.0.20.11:6379 <node-id>

7. 故障排查顺序

redis-cli -c -h 10.0.20.11 CLUSTER INFO
redis-cli -c -h 10.0.20.11 CLUSTER NODES
redis-cli --cluster check 10.0.20.11:6379
redis-cli -c -h 10.0.20.11 INFO replication

依次检查:服务端口和 bus 端口、节点时间、announce 地址、slot 覆盖、主节点是否有健康副本。Docker/NAT 环境尤其要正确设置 cluster-announce-ipcluster-announce-portcluster-announce-bus-port

cluster-require-full-coverage yes 会在 slot 覆盖不完整时停止服务以保护一致性,但可能扩大不可用范围。是否关闭必须由业务一致性要求决定。

8. 生产变更检查

  • 有最新备份和明确回滚方案;
  • 当前集群为 ok,没有 fail/pfail 节点;
  • 客户端支持重定向和拓扑刷新;
  • 迁 slot 速率经过压测;
  • 不同时重启同一主节点和它的副本;
  • 扩缩容后重新检查 slot、复制关系和容量分布。