type
status
date
slug
summary
tags
category
password
1、集群部署
Broker 有以下几种主流部署架构,可靠性从上往下递增:
部署方式 | 优点 | 缺点 | 适用场景 |
单个 Master | 配置简单 | 风险极大 | 测试环境 |
多 Master | 配置简单,单个 Master 宕机或重启维护对应用无影响,性能最高。 | 单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到影响。如果磁盘损坏,该机器上面的所有消息都会丢失。 | 测试环境、或消息可容忍临时丢失的性能优先场景 |
多 Master 多 Slave 模式,异步复制 | 即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,因为 Master 宕机后,消费者仍然可以 从 Slave 消费,此过程对应用透明。不需要人工干预。性能同多 Master 模式几乎一样。 | Master 宕机,磁盘损坏情况,会丢失少量消息。 | 大多数生产环境,平衡性能与可靠性 |
多 Master 多 Slave 模式,同步复制 | 数据与服务都无单点,Master 宕机情况下,消息无延迟,服务可用性与数据可用性都非常高 | 性能比异步复制模式略低,大约低 10%左右,发送单个消息的 RT 会略高。 | 金融、交易等对数据一致性要求极高的核心业务 |
DLedger模式(基于Raft协议) | 可靠性极高(自动容灾切换),数据一致性高(强一致性) | 至少需要3个节点,4.5版本后支持 | 要求自动故障转移的高可用场景 |
最佳实践如下

- NameServer:集群部署,无状态,节点之间没有联系,每个 NameServer 保存所有 Broker 的信息。
- Broker:集群部署,采用多 Master 多 Slave 的部署方式,部署多个 Master,每个 Master 至少对应一个 Slave。Master 和 Slave 的角色配置如下:
- 如果对消息丢失容忍度很低,官方建议采用
SYNC_MASTER + AYNC_FLUSH
的方式,这样只有 Master 和 Slave 在刷盘前同时挂掉,且都没有刷到磁盘,消息才会丢失。这样是一个兼顾性能和可靠性的较好平衡。 - 如果对消息丢失容忍度较高的,则建议采用
ASYNC_MASTER + ASYNC_FLUSH
的方式。
- Producer:集群部署,无状态,Producer 与 NameServe r集群中的其中一个节点(随机选择)建立长连接,定期从 NameServer 获取Topic路由信息,并向提供 Topic 服务的 Master 建立长连接,且定时向 Master 发送心跳。
- Consumer:集群部署,无状态,Consumer 与 NameServer 集群中的其中一个节点(随机选择)建立长连接,定期从 NameServer 获取 Topic 路由信息,并向提供 Topic 服务的 Master、Slave 建立长连接,且定时向 Master、Slave 发送心跳,Consumer既可以从 Master 订阅消息,也可以从 Slave 订阅消息。
2、负载均衡
RocketMQ 的负载均衡是在生产者和消费者的客户端完成的。
组件 | 负载均衡核心机制 | 关键目标 |
生产者 | 采用轮询策略,将消息依次发送至 Topic 下的不同消息队列(MessageQueue)。 | 让消息均匀分布到各个Broker上,避免单个队列或Broker压力过大。 |
消费者 (4.x及早期版本) | 采用队列粒度的负载均衡。将Topic下的所有队列平均分配给同一消费组(Consumer Group)内的各个消费者实例。 | 保证同一队列的消息只被一个消费者处理(集群模式下),避免重复消费。 |
消费者 (5.x版本) | 引入消息粒度的负载均衡(特别是POP模式)。允许同一队列的消息被同一消费组内的多个消费者并行拉取和处理,服务端通过消息锁机制保证消息不重复。 | 实现更精细的负载分摊,提升资源利用率和系统弹性。 |
2.1 生产者的均衡负载
生产者的任务是将消息发送到主题(Topic)下的多个队列中。在确定消息对应的队列时候,通常不会直接指定某个队列(当然也可以手动指定),而是通过内置的负载均衡算法来选择。根据消息类型的不同,它会采用两种策略:
策略模式 | 适用消息类型 | 工作原理 | 特点与建议 |
RoundRobin 轮询模式 | 普通消息、事务消息、定时/延时消息(非顺序消息) | 以消息为粒度,简单轮询主题下的所有可用队列,使每条消息尽可能均匀地落在不同队列上。 | 默认策略,能最大化实现消息分布的均匀性,充分发挥主题的传输能力。 |
MessageGroupHash 哈希模式 | 顺序消息 | 以消息组(Message Group) 为粒度,通过哈希算法将同一消息组的消息始终发送到同一个队列中。 | 保证同一消息组内消息的顺序性。设计时应使消息组尽可能离散(如使用不同订单ID),避免大量消息集中在少数队列导致热点问题。 |
2.2 消费者的均衡负载
队列粒度负载均衡(4.x及早期版本主流)
在4.x等早期版本中,负载均衡的单元是消息队列。
- 工作方式:消费组内的多个消费者会按照特定的分配策略(如默认的
AllocateMessageQueueAveragely
平均分配算法)来瓜分 Topic 下的所有队列。每个队列在同一个时刻只能被消费组内的一个消费者绑定和消费。
- 重要限制:这种模式下,为了确保每个消费者都能分配到资源,通常要求队列数量 >= 消费者数量。如果消费者数量超过队列数,多出的消费者将无法消费消息。
- 触发时机:消费者启动、下线或定时任务(默认每20秒)都会触发负载均衡,以重新分配队列。
消息粒度负载均衡(5.x版本重要革新)
RocketMQ 5.x版本引入了更先进的消息粒度负载均衡,旨在解决队列粒度负载均衡可能导致的资源利用不均衡问题。
- 工作方式:在POP消费模式下,消息的分配单位从整个队列细化到了单条消息。同一消费组内的多个消费者可以同时从同一个队列中拉取不同的消息进行处理。
- 如何保证不重复:服务端会跟踪每条消息的状态。一旦某个消费者拉取了一条消息,这条消息会被暂时“锁定”,在该消息被确认消费成功或超时之前,不会分配给其他消费者,从而保证了消息不会被重复消费。
- 顺序消息处理:对于顺序消息,5.x版本通过锁定同一消息组(MessageGroup)内的消息状态,确保了即使该组消息被不同消费者处理,也能严格按照存储顺序串行消费。
3、消息同步
3.1 消息的主从同步和刷盘策略
消息同步策略是指主从节点间的消息同步方式。RocketMQ 主要有两种消息同步策略:
特性维度 | 异步复制 (ASYNC_MASTER) | 同步复制 (SYNC_MASTER) |
核心机制 | 节点(Master)在收到生产者发送的消息后,需要等待从节点(Slave)将消息复制成功,再向生产者返回一个成功的响应。 | 主节点在消息写入本地后,立即向生产者返回一个成功的响应。后台线程异步地将消息复制给从节点。主节点不会等待从节点的结果。 |
数据一致性 | 最终一致,主从有短暂延迟 | 强一致,主从同时成功才返回 |
性能影响 | 低,不阻塞生产者发送流程 | 高,需等待从节点确认,增加延时 |
消息可靠性 | 较低,主节点宕机可能导致少量消息丢失 | 极高,确保消息已安全复制到从节点 |
适用场景 | 追求高吞吐、可容忍极小概率消息丢失的业务,如日志收集、非核心通知 | 对数据强一致性要求高的核心业务,如金融交易、库存扣减 |
消息的刷盘策略是指消息在写入内存后何时以及如何持久化到磁盘。RocketMQ 也提供了两种消息刷盘策略:
特性 | 同步刷盘 (SYNC_FLUSH) | 异步刷盘 (ASYNC_FLUSH) |
核心机制 | 消息写入内存后,立即唤醒刷盘线程,必须等待消息持久化到磁盘后才会向生产者返回成功响应。 | 消息写入操作系统PageCache(页缓存) 后立即返回成功响应,由后台线程定期将一批消息刷入磁盘。 |
数据可靠性 | 极高。只要主节点(Broker)未永久损坏,理论上不会丢失消息,适用于金融、交易等核心场景。 | 较高,但极端情况下会丢失。如果Broker意外宕机,尚未刷盘的消息会丢失。 |
吞吐量与性能 | 较低。因为每次写入都涉及一次磁盘I/O,延迟较高,吞吐量相对较小。 | 非常高。通过批量刷盘减少了磁盘I/O次数,充分利用了OS的PageCache优势,延迟低,吞吐量大。 |
要设置消息的同步和刷盘策略,需要修改
broker.conf
配置文件,设定以下两个关键参数:brokerRole
:定义主节点的复制方式。SYNC_MASTER
:指定该 Broker 作为主节点,并采用同步复制模式。ASYNC_MASTER
:指定该 Broker 作为主节点,并采用异步复制模式。SLAVE
:指定该 Broker 作为从节点。
flushDiskType
:定义消息刷盘策略。ASYNC_FLUSH
:异步刷盘,消息写入操作系统页缓存(PageCache)后就返回,性能高,但有宕机丢消息风险。SYNC_FLUSH
:同步刷盘,消息必须持久化到磁盘后才返回,可靠性高,但性能损耗大
一种常见的平衡性能与可靠性的配置组合是:
SYNC_MASTER
(同步复制) + ASYNC_FLUSH
(异步刷盘)。这样既保证了主从节点间数据的强一致性,又利用异步刷盘保持了较高的写入性能。配置如下所示:4、Rebalance
RocketMQ 的 Rebalance(重平衡)机制是其在集群模式下的 Consumer Group 内各个 Consumer 实例重新分配 Message Queue 的过程。
Rebalance 产生的负面影响:
- 消费暂停:在 Rebalance 过程中,消费者需要释放掉不再由其负责的队列,并准备新的队列,这会暂时中断消费流程。
- 重复消费:对于队列粒度负载均衡,如果消费者采用异步提交消费位移的方式,在 Rebalance 发生时,新接管的消费者可能从稍早的位移开始消费,导致消息重复。建议根据业务容忍度合理配置异步提交间隔。
4.1 Rebalance的触发时机
Rebalance 的触发通常源于以下两类变化:
- 消费者组的消费者数量变化:例如有新的消费者实例加入或退出(如扩容、缩容、实例宕机、网络异常)。
- Topic 下的 Queue 数量变化:例如 Broker 宕机、运维操作导致的队列下线,或队列的扩容/缩容。
当 Broker 感知到这些变化时,会通知消费者组内的所有实例触发 Rebalance。此外,消费者客户端默认也会每隔 20 秒自动执行一次 Rebalance,以适应可能的元数据变化。
4.2 负载均衡策略
特性维度 | 消息粒度负载均衡 (RocketMQ 5.0+ 默认 for Push/SimpleConsumer) | 队列粒度负载均衡 (传统方式,PullConsumer 及 5.0 前版本) |
分配单位 | 单条消息 | 整个消息队列 |
核心机制 | 同一队列的消息可被组内多个消费者并发消费,服务端通过消息锁避免重复消费 | 一个队列在同一时刻只分配给一个消费者 |
优点 | 分摊更均匀,无需担心消费者与队列数量不匹配,对非对等消费者友好 | 保证同一队列消息的顺序性,利于流式处理、聚合计算 |
缺点/注意 | 无法指定特定消费者处理特定消息;顺序消息需按消息组串行处理 | 易出现负载不均(消费者与队列数不匹配时);Rebalance 期间可能导致重复消费和消费暂停 |
适用场景 | 绝大多数在线业务处理、微服务解耦 | 强顺序消息处理、流计算、批处理 |
在队列粒度负载均衡中,RocketMQ 提供了多种内置策略来决定如何将队列分配给消费者。以下是一些常见策略:
策略名 | 说明 |
AllocateMessageQueueAveragely | 默认策略。将队列尽可能平均地分配给所有消费者。例如9个队列3个消费者,则每个消费者分得3个队列。 |
AllocateMessageQueueAveragelyByCircle | 采用轮询方式分配。例如队列q1, q2, q3和消费者c1, c2,则分配结果为c1: [q1, q3], c2: [q2]。 |
AllocateMachineRoomNearby | 机房优先策略。优先将同机房的队列分配给同机房的消费者,若本地无消费者,再分配给其他机房的消费者。 |
AllocateMessageQueueConsistentHash | 使用一致性哈希算法,能在消费者数量变动时最小化队列的重新映射范围。 |
你可以通过以下方式为消费者指定策略:
- Author:mcbilla
- URL:http://mcbilla.com/article/27785c7d-7c1d-8001-8527-cf8749eb8a0a
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!