Redis Cluster 在网络分区场景下的处理机制
假设 Redis Cluster 包含 5 个主节点 A、B、C、D、E(用户提到的“D、D”可能为笔误),网络分区导致 A 和 B 与 C、D、E 之间无法通信,但 A 和 B 内部通信正常。此时集群将基于以下机制运作:
1. 故障检测与多数派(Quorum)判定
- Redis Cluster 要求多数主节点(N/2 +1)达成共识才能触发故障转移。对于 5 个主节点,多数派为 3 个节点。
- 分区影响:
- C、D、E 分区(3 节点):可达成多数派,具备决策权。
- A、B 分区(2 节点):无法达成多数派,无决策权。
2. 分区后的行为
(1)C、D、E 分区的行为
-
标记故障节点:
- C、D、E 无法与 A、B 通信,超过
cluster-node-timeout
(默认 15 秒)后,将 A、B 标记为 PFAIL(疑似下线)。 - 通过 Gossip 协议交换信息,确认 A、B 的状态。由于 C、D、E 占据多数派,最终将 A、B 判定为 FAIL(已下线)。
- C、D、E 无法与 A、B 通信,超过
-
触发故障转移:
- 若 A、B 负责的哈希槽(Hash Slots)存在**从节点(Replica)**且位于 C、D、E 分区,从节点将被提升为新的主节点,接管原槽位。
- 若无从节点可用,A、B 负责的槽位将处于 FAIL 状态,导致相关数据不可访问。
-
集群状态调整:
- 新主节点接管槽位后,集群元数据更新,C、D、E 分区继续正常服务,但仅覆盖原 C、D、E 及新接管的槽位。
(2)A、B 分区的行为
- 无法达成共识:
- A、B 因仅有 2 个节点,无法形成多数派,无法将 C、D、E 标记为 FAIL。
- 仍认为自己是主节点,继续处理请求,但受限于以下机制:
- 写入拒绝:Redis Cluster 默认要求主节点在多数派存活时才能写入。若 A、B 无法感知到多数节点,可能拒绝写入(依赖
cluster-require-full-coverage
配置)。 - 数据不一致风险:若配置允许写入(如
cluster-allow-writes
开启),A、B 可能继续接受写入,导致与 C、D、E 分区的数据分叉。
- 写入拒绝:Redis Cluster 默认要求主节点在多数派存活时才能写入。若 A、B 无法感知到多数节点,可能拒绝写入(依赖
3. 数据一致性与服务可用性
-
C、D、E 分区:
- 服务可用,接管了原集群的多数槽位(假设从节点存在)。
- 数据一致性由故障转移机制保障,新主节点同步旧主未复制的数据(若从节点数据未过期)。
-
A、B 分区:
- 若允许写入,数据将独立更新,恢复网络后需人工介入合并冲突。
- 若拒绝写入,客户端将收到错误(如
CLUSTERDOWN
),服务部分不可用。
4. 网络恢复后的修复
-
节点重新加入集群:
- A、B 重新连接后,发现自身槽位已被 C、D、E 分区的新主节点接管,自动降级为从节点(若配置允许)。
- 从新主节点同步数据,丢弃隔离期间的本地写入(若未持久化)。
-
数据冲突处理:
- 若 A、B 在隔离期间接受写入,需人工比对
AOF
或RDB
文件,合并冲突数据。
- 若 A、B 在隔离期间接受写入,需人工比对
5. 配置优化建议
- 合理设置
cluster-node-timeout
:根据网络稳定性调整超时时间,避免误判。 - 部署从节点:确保每个主节点有至少一个从节点位于不同物理分区,提升容错能力。
- 控制写入策略:避免在少数派分区允许写入(保持
cluster-require-full-coverage=yes
默认配置)。
总结
Redis Cluster 在网络分区时,多数派分区(C、D、E) 将接管故障节点职责,保障服务可用性;少数派分区(A、B) 因无法达成共识,可能拒绝写入或引发数据不一致。最终恢复需依赖人工干预,强调合理配置与容灾设计的重要性。