跳到主要内容
版本: 5.0

主从自动故障转移模式

架构图

本文档主要介绍如何部署支持主从自动切换的 RocketMQ 集群。其架构如上图所示,主要新增了支持主从自动切换的 controller 组件,该组件可独立部署,也可内嵌在 NameServer 中。

参考

更多详细内容,请参考设计思想快速开始

Controller 部署

Controller 组件提供主节点选举功能。如果 Controller 需要高可用,则需要部署三个或以上副本(遵循 Raft 多数协议)。

提示

如果 controller 只部署单副本,它仍能完成 broker 故障转移,但如果单点 controller 出现故障,会影响切换能力,但不影响现有集群的正常收发。

Controller 部署方式有两种,一种是内嵌在 NameServer 中部署,可通过设置 enableControllerInNamesrv 开启(可选择性开启,非必需在每个 NameServer 上都开启)。在此模式下 NameServer 本身仍是无状态的,这意味着 NameServer 在嵌入模式下故障,只会影响切换能力,不影响原有的路由获取等功能。另一种是独立部署 controller 组件。

Controller 内嵌 NameServer 部署

内嵌部署图

Controller 内嵌 NameServer 部署时,只需要在 NameServer 配置文件中设置 enableControllerInNamesrv=true,并填写 controller 配置即可。

enableControllerInNamesrv = true
controllerDLegerGroup = group1
controllerDLegerPeers = n0-127.0.0.1:9877;n1-127.0.0.1:9878;n2-127.0.0.1:9879
controllerDLegerSelfId = n0
controllerStorePath = /home/admin/DledgerController
enableElectUncleanMaster = false
notifyBrokerRoleChanged = true

参数说明:

  • enableControllerInNamesrv: 是否在 Nameserver 中启用 Controller,默认为 false。
  • controllerDLegerGroup: DLedger Raft Group 的名称,在同一个 DLedger Raft Group 中必须保持一致。
  • controllerDLegerPeers: DLedger Group 内节点间的端口信息,在同一个 Group 内节点间的配置必须保持一致。
  • controllerDLegerSelfId: 节点 ID,必须是 controllerDLegerPeers 之一;在同一个 Group 内每个节点必须唯一。
  • controllerStorePath: Controller 日志存储位置。Controller 是有状态的,Controller 重启或崩溃时,需要依赖日志恢复数据。该目录非常重要,不能随意删除。
  • enableElectUncleanMaster: 是否可以从 SyncStateSet 外部选举 Master。如果为 true,可能会选择一个数据过时的副本作为 Master,并丢失消息。默认为 false。
  • notifyBrokerRoleChanged: Broker 副本组角色变更时是否主动通知,默认为 true。

参数设置完毕后,通过指定配置文件即可启动 Nameserver。

$ nohup sh bin/mqnamesrv -c namesrv.conf &

Controller 独立部署

架构图

独立部署运行如下脚本

$ nohup sh bin/mqcontroller -c controller.conf &

mqcontroller 脚本位于源码包的 distribution/bin/mqcontroller,配置参数同内嵌模式。

注意

独立部署 Controller 后,仍需单独部署 NameServer 提供路由发现能力。

Broker 部署

Broker 启动方式与之前相同,新增以下参数

  • enableControllerMode: Broker Controller 模式的总开关。只有该值为 true 时,才会启用主从自动切换模式。默认为 false。
  • controllerAddr: Controller 的地址,多个 Controller 之间用分号分隔。例如,controllerAddr = 127.0.0.1:9877;127.0.0.1:9878;127.0.0.1:9879
  • syncBrokerMetadataPeriod: 同步 Broker 副本信息给 Controller 的时间间隔。默认为 5000 (5s)。
  • checkSyncStateSetPeriod: 检查 SyncStateSet 的时间间隔,检查 SyncStateSet 可能会收缩 SyncState。默认为 5000 (5s)。
  • syncControllerMetadataPeriod: 同步 Controller 元数据的时间间隔,主要用于获取活跃 Controller 的地址。默认为 10000 (10s)。
  • haMaxTimeSlaveNotCatchup: Slave 未赶上 Master 的最大时间间隔,如果 SyncStateSet 中的 slave 超过此时间间隔,则会从 SyncStateSet 中移除。默认为 15000 (15s)。
  • storePathEpochFile: Epoch 文件的位置。Epoch 文件非常重要,不能随意删除。默认在 store 目录下。
  • allAckInSyncStateSet: 如果该值为 true,只有当消息复制到 SyncStateSet 中的每个副本时,才会向客户端返回成功,确保消息不丢失。默认为 false。
  • syncFromLastFile: 如果 slave 是空白磁盘启动,是否从最后一个文件复制。默认为 false。
  • asyncLearner: 如果该值为 true,副本将不会进入 SyncStateSet,即不会被选举为 Master,而是始终作为 learner 副本并执行异步复制。默认为 false。
  • inSyncReplicas: 需要保持同步的副本组数量,默认为 1,当 allAckInSyncStateSet=true 时此参数无效。
  • minInSyncReplicas: 需要保持同步的最小副本组数量。如果 SyncStateSet 中的副本数量小于 minInSyncReplicas,putMessage 将返回 PutMessageStatus.IN_SYNC_REPLICAS,默认为 1

在 Controller 模式下,Broker 配置必须设置 enableControllerMode=true 并填写 controllerAddr,并使用以下命令启动

$ nohup sh bin/mqbroker -c broker.conf &
注意

在主从自动切换模式下,Broker 无需指定 brokerId 和 brokerRole,这些将由 controller 组件分配。

兼容性

该模式对任何客户端 API 没有做任何改动或修改,与客户端不存在兼容性问题。

Nameserver 本身没有改动,与 Nameserver 不存在兼容性问题。如果 enableControllerInNamesrv 开启,且 controller 参数配置正确,则 Controller 功能开启。

如果 Broker 设置为 enableControllerMode=false,仍会按之前方式运行。如果 enableControllerMode=true,则 Controller 必须部署,且参数配置正确,才能正常运行。

具体行为如下表所示

旧版 Nameserver旧版 Nameserver + 独立部署 Controller新版 Nameserver 启用 Controller新版 Nameserver 禁用 Controller
旧版 Broker正常运行,无法故障转移正常运行,无法故障转移正常运行,无法故障转移正常运行,无法故障转移
新版 Broker 启用 Controller 模式无法正常上线正常运行,可故障转移正常运行,可故障转移无法正常上线
新版 Broker 禁用 Controller 模式正常运行,无法故障转移正常运行,无法故障转移正常运行,无法故障转移正常运行,无法故障转移

升级注意事项

从以上兼容性说明可以看出,NameServer 可以正常升级,不存在兼容性问题。在 Nameserver 不升级的情况下,也可独立部署 Controller 组件,从而获取切换能力。对于 Broker 升级,存在两种情况

  1. 主从部署升级为 Controller 切换架构

    可带数据原地升级。对于每组 Broker,停掉主从 Broker,并确保主从的 CommitLog 对齐(可在升级前一段时间内停止该组 Broker 写入,或通过复制方式确保一致),升级包后重启即可。

    注意

    如果主从 CommitLog 不对齐,则需要确保先主后从的顺序上线,否则可能因为数据截断而丢失消息。

  2. DLedger 模式升级为 Controller 切换架构

    由于 DLedger 模式和主从模式的消息数据格式差异,不存在带数据原地升级。在部署多组 Broker 的情况下,可在一组 Broker 上停止写入一段时间(只要确认所有存量消息已消费完毕),然后升级并部署 Controller 和新的 Broker。这样,新的 Broker 会从现有 Broker 消费消息,现有 Broker 会从新的 Broker 消费消息,直到消费平衡,然后现有 Broker 即可下线。