图说RocketMQ5.0的Broker的主备自动切换的设计与实现
持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
RocketMQ5.0用新开发的 DLedger Controller 模式增强了以前的 DLedger 模式,下面就来从设计聊一下 DLedger Controller 模式是如何来实现Broker的主备自动切换。我们从以下几个方面来分析:
- RocketMQ5.0 整体的架构改动
- DLedger Controller如何实现Broker选主(主备自动切换关键)
- 参与Broker选主的扩容和缩容(哪些Broker有资格参加选主)
Tips: RocketMQ 源码版本5.0.0
1. RocketMQ5.0 主备自动切换架构

相比之前的高可用架构,增加了一个DLedger Controller用来实现Broker主备的自主切换和高可用。RocketMQ5.0的主备模式解决RocketMQ4.x哪些问题:
- 想要具备选举切换的能力,单组 Broker 内的副本数必须 3 副本及以上
- 副本 ACK 需要严格遵循 Raft 协议多数派的限制,3 副本需要 2 副本 ACK 后才能返回,5 副本需要 3 副本 ACK 后才能返回,副本越多返回ACK的时间越长。这会导致性能下降
- DLedger 模式下,由于存储库使用了 OpenMessaging DLedger 存储,因此无法复用 RocketMQ 原生的存储和复制的能力(比如 transientStorePool 和零拷贝能力),且对维护造成了困难。
在RocketMQ5.0版本新增了DLedger Controller模式来解决上面对的痛点。
DLedger Controller的部署模式有两种:
-
独立部署
单独部署DLedger Controller集群
-
内嵌NameServer部署(推荐)
RocketMQ5.0在默认情况下是不会开启内嵌Controller的,通过设置配置:
enableControllerInNamesrv=true
DLedger Controller主要用于Broker的选主,而数据的存储能力还是依靠RocketMQ Broker。 这里可以很好使用到MQ原生的存储能力便于维护。
2. DLedger Controller如何实现Broker选主

Broker的选主发起主要有三种情况:
- 通过admin命令人为主动发起重新选主(运维命令)
- RocketMQ集群刚搭建Broker启动注册Broker到DLedger Controller,DLedger Controller还没有选主,然后触发选主操作。(系统初始化)
- RocketMQ Broker Master Inactive,会触发DLedger Controller选主Broker
Broker 组第一次上线时,调用该方法也没有 Master,此时会让调用的 broker 试着成为 Master,形成 ElectMasterEvent 事件日志并提交提案,副本组中第一个成功应用 ElectMasterEvent 事件日志的 Broker 会成为 Master,并形成只有自己的 SyncStateSet 列表。
2.1 选主的元数据
选主Broker注册到 DLedger Controller 的元数据:
- clusterName
- brokerName
- address
- epoch
- maxOffset
这些元数据主要用来选主判断。
2.2 选主的流程
ELectMaster 主要是在某 Broker 副本组的 Master 下线或不可访问时,重新从 SyncStateSet 列表里面选出一个新的 Master,该事件由 Controller 自身发起。 这里主要是利用了心跳机制, Broker 定期会和 Controller 上报心跳, Controller 也会定期扫描超时的 Broker (scanNotActiveBroker)。如果某个 Broker 心跳超时, Controller 会判断是否为 Master (BrokerId = 0), 如果是 Master, 则会发起 ElectMaster, 选举新的 Broker Master。 选举 Master 的方式比较简单,我们只需要在该组 Broker 所对应的 SyncStateSet 列表中,挑选一个仍然存活的副本(心跳未超时)出来成为新的 Master 即可,选举出来生成 ElectMaster 事件,通过 DLedger 共识后应用到内存元数据,并将结果通知对应的 Broker 副本组(Broker 本身也会有有轮询机制来获取自身副本组的 Master 信息(getReplicaInfo)做进一步保证,防止通知丢失)。 此外, Controller 增加 enableElectUnCleanMaster 参数,这时如果 SyncStateSet 没有符合要求的副本,可以在当前所有的存活的副本中选,但可能大量消息丢失。
Tips: 具体可以参照《RocketMQ5.0主备自动切换模式Broker选主详解》