Skip to content

网络分区 ​

网络分区指节点之间网络不通、但节点各自仍在运行的状态。每个分区都以为对方挂了、各自继续工作,处理不好就会出现两个集群同时服务、数据分叉。

1. 什么是网络分区 ​

txt
正常状态:
  Node 1 ←──→ Node 2 ←──→ Node 3

网络分区:
  Node 1 ←──→ Node 2    Node 3(隔离)
  [分区 1]              [分区 2]

分区和节点宕机的本质区别是,分区里每个节点都还在运行,只是互相联系不上。宕机是少了一个节点,分区是分裂成多个。分区更难自动处理,因为节点无法仅凭本地观察判断远端节点是宕机还是网络隔离。

2. 分区对数据的影响 ​

RabbitMQ 4.3 起,元数据存储(Khepri)、Quorum Queue、Stream 这三类核心复制组件都基于 Raft。分区时,一个 Raft 共识组如果失去多数派,就无法继续提交需要多数派确认的状态变更。

队列类型分区行为
Classic Queue(单节点)数据只在所属节点,别的分区访问不到
Quorum Queue副本组多数派可用才继续处理,少数派无法提交状态变更
Stream副本组多数派可用才推进复制,消费端能否读取取决于目标副本和连接路径

镜像队列是 3.x 的复制方案,4.0 已移除,见镜像队列。它分区时可能出现多个 Master、两边各自接受写入;网络恢复后的处理取决于配置的策略,autoheal 会选一边重启另一边、丢掉被重启侧的数据,这是它被 Quorum Queue 取代的原因之一。

3. 分区处理策略:历史与现状 ​

RabbitMQ 4.3 起,Mnesia 被移除,Khepri 成为唯一元数据存储,元数据存储(Khepri)、Quorum Queue、Stream 全部基于 Raft。分区时,每个 Raft 共识组能否继续提交状态变更由该组多数派决定,不再有可配置的分区处理策略。

旧版 Mnesia 时代的三种策略已在 4.3 移除。这些配置键仍会被 4.3 节点接受,但不会产生任何效果,官方建议升级前从 rabbitmq.conf 中删除。

旧策略行为备注
ignore不做自动处理,人工介入Mnesia 时代的选项
pause_minority节点少的一边自动暂停Mnesia 时代的选项
autoheal自动选一边重启另一边Mnesia 时代易因网络抖动反复重启,官方不推荐生产使用

这些旧策略只在使用 Mnesia 的旧版集群里有意义,4.3 已随 Mnesia 一并移除。当前版本判断分区影响,应看具体复制组(元数据存储、各队列)的多数派是否可用,而不是依赖自动暂停或自动选边。

4. Quorum Queue 如何应对分区 ​

Quorum Queue 用 Raft 复制队列状态。它能否继续处理写入,取决于这个队列的副本组是否还有多数派可用,而不是集群里总共有多少节点。五节点集群里只部署在三个节点上的 Quorum Queue,多数派是这三个副本中的两个,与集群总节点数无关。

txt
3 副本的 Quorum Queue,Node 3 被隔离:
  Node 1 + Node 2(多数派)→ 继续提交状态变更
  Node 3(少数派)→ 无法凑齐多数票,无法提交新的状态变更

网络恢复后:
  Node 3 通过 Raft 日志复制追赶当前状态

少数派一侧无法提交需要共识的状态变更,客户端发起的请求可能失败或超时,具体表现取决于请求路径和连接状态。这不是因为配置了什么策略,而是 Raft 协议本身要求多数派确认才提交。

注意元数据存储(Khepri)和每个 Quorum Queue 是两个独立的 Raft 共识组。元数据多数派可用,不代表某个队列的副本组多数派也可用,两者成员范围不一定相同,判断时不能混为一谈。

5. 分区后的检查与恢复 ​

网络恢复后,先确认节点之间已经重新建立通信,再检查集群状态和受影响队列的可用性。不要只看节点重新显示为运行,就认定所有队列都已恢复。

bash
# 查看集群节点可达状态
rabbitmq-diagnostics cluster_status

# 查看 Quorum Queue 的 leader 与副本状态
rabbitmq-queues quorum_status <queue>

检查重点:

  • 集群节点是否重新互通,是否仍有节点处于隔离或异常状态
  • 受影响的 Quorum Queue 是否重新具备多数副本,能否继续处理操作
  • 副本是否正在通过 Raft 日志追赶状态,队列是否恢复正常服务

Quorum Queue 的副本会通过 Raft 日志复制追赶缺失状态,通常不需要手动合并数据。是否需要重启节点,应根据节点实际状态和官方故障处理指南判断,不要把 stop_app、start_app 当成遇到分区后的默认操作。

6. 预防与监控 ​

  • 节点部署位置按可用性目标选择:同一机房延迟低,但无法抵御机房级故障;跨机房能分散基础设施故障风险,但链路延迟和故障条件更复杂。Raft 复制对网络延迟敏感,跨机房部署要谨慎评估网络质量。
  • 需要数据复制时优先 Quorum Queue,但要按副本组的多数派状态判断可用性,而不是只看队列类型。
  • 监控节点间网络延迟和丢包,而不是只看节点是否存活;同时关注 Raft 选举日志。
  • heartbeat 是客户端连接级检测,不能替代节点间的分区检测。官方建议大多数环境从 5-20 秒评估 heartbeat timeout(默认 60 秒),过短会误判,过长则延迟发现连接故障。节点间故障由 Raft 的自适应故障检测器发现,比心跳机制更快、对延迟抖动更不敏感。

Released under the MIT License.