[TOC] #### 1. 前言 --- 上一讲我们聊了镜像队列:把数据复制到多个节点,实现高可用 但镜像队列有一些设计上的问题,RabbitMQ 官方后来不再推荐使用它,取而代之的是Quorum Queue(仲裁队列) 这一讲我们来聊聊:为什么需要 Quorum Queue,它解决了什么问题 ? #### 2. 镜像队列到底有什么问题 --- 先回顾一下镜像队列的工作方式: + 一个主节点,多个镜像节点 + 所有读写走主节点 + 主节点把消息同步到镜像 看起来没问题,但实际运行中会遇到这些情况: 问题一:消息可能丢 主节点收到一条消息,还没来得及同步给镜像,主节点就挂了 镜像升级为主节点,但这条消息不存在,消息丢了 镜像队列的同步是异步的,不保证每条消息都同步完成 问题二:主节点是单点瓶颈 所有 Producer 和 Consumer 都连主节点 镜像节点平时只是「待命」,不参与读写,主节点压力大,镜像节点闲着 问题三:脑裂风险 网络分区的时候,可能出现两个节点都认为自己是主节点 两边都在接受写入,数据不一致,恢复之后谁的数据算数 ?很难处理 #### 3. Quorum Queue 的设计思路 --- RabbitMQ 官方为了解决这些问题,在 3.8 版本推出了 Quorum Queue 它的核心思路和镜像队列不同: + Quorum Queue 不再依赖传统的 Master + Mirror 同步模式 + 它通过多数节点确认机制来保证数据可靠性,写入一条消息时,需要大多数节点确认收到,才算写入成功 比如你有 3 个节点: + 写入节点 A ✅ + 写入节点 B ✅ + 写入节点 C 还没收到 2 个节点确认了,超过半数(3/2 + 1 = 2),消息算写入成功,即使节点 C 挂了,消息也不会丢 #### 4. 这种方式解决了什么问题 --- 一、解决了消息丢失 镜像队列是异步同步,消息可能没同步完就丢了 Quorum Queue 要求大多数节点确认,保证消息已经写入多个节点,只要不是大多数节点同时挂,消息就不会丢 二、降低了主节点瓶颈 Quorum Queue 通过新的复制机制降低了镜像队列的很多问题 但消息写入仍然需要协调多个节点完成确认,不存在「完全没有瓶颈」的情况 三、减少了脑裂风险 用「大多数确认」的机制来保证一致性 网络分区时,只有拿到大多数节点确认的一方才能继续工作,大幅降低了脑裂带来的数据不一致风险 #### 5. 生活中的例子 --- 镜像队列就像一个老师在台上讲课,学生在下面抄笔记 老师讲完了,学生可能还没抄完,如果老师突然走了,学生手里的笔记可能不完整 Quorum Queue 就像小组讨论:一个方案要大多数人同意才能通过 即使有一个人缺席,不影响决策,而且不会出现两边各做各的决定 #### 6. 什么时候用 Quorum Queue --- RabbitMQ 官方后来逐步弱化镜像队列,并在新版本中把 Quorum Queue 作为主要高可用方案推荐 如果你需要高可用队列,优先使用 Quorum Queue,而不是镜像队列 特别是: + 对消息可靠性要求高(订单、支付) + 节点数量 ≥ 3(需要奇数个节点来选举) + 不想处理脑裂问题 Quorum Queue 是镜像队列的替代品,不是补充,但 Quorum Queue 也有局限: 一、需要奇数个节点:如 3 个、5 个、7 个,偶数个节点会出现「平票」的情况,影响选举 二、性能略有下降:每条消息要等大多数节点确认,写入延迟比镜像队列稍高,但换来的是更高的可靠性 三、不支持所有功能:Quorum Queue 不支持优先级队列、TTL 等部分高级特性,如果业务依赖这些特性,需要评估一下 #### 7. 本文小结 --- 镜像队列 VS 仲裁队列 | | 镜像队列 | Quorum Queue | | ------------ | ------------ | ------------ | | 数据同步 | 异步 | 大多数确认 | | 消息可靠性 | 可能丢 | 不容易丢 | | 主节点瓶颈 | 有 | 降低但仍有协调开销 | | 脑裂风险 | 有 | 大幅减少 | | 官方推荐 | 不再推荐 | 推荐使用 | 核心一句话:Quorum Queue 用「大多数确认」的机制,解决了镜像队列的可靠性和一致性问题 下一讲,我们来聊怎么把这些东西部署到实际环境中