跳到主要内容

集群部署

生产环境中,为了保证消息系统的高可用和高性能,需要部署 RocketMQ 集群。本章将详细介绍各种集群部署方案。

部署架构概述

RocketMQ 支持多种部署架构,根据业务需求选择合适的方案:

架构模式说明适用场景
单 Master只有一个 Broker 节点开发测试环境
多 Master多个 Master Broker,无 Slave允许少量消息丢失的场景
多 Master 多 Slave(异步复制)Master 异步复制到 Slave高可用,允许少量丢失
多 Master 多 Slave(同步双写)Master 同步写入 Slave高可用,不丢失消息
Controller 模式支持自动主从切换生产环境,需要自动故障转移

单 Master 部署

单 Master 部署最简单,但存在单点故障风险,仅适用于开发测试环境。

启动命令

# 启动 NameServer
nohup sh bin/mqnamesrv &

# 启动 Broker
nohup sh bin/mqbroker -n localhost:9876 &

注意事项

  • Broker 宕机会导致服务不可用
  • 机器故障可能导致消息丢失
  • 仅用于开发测试,不推荐生产使用

多 Master 部署

多 Master 部署没有 Slave 节点,所有 Broker 都是 Master,提供较高的吞吐量。

配置示例

Broker-A 配置(broker-a.properties)

# 基础配置
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
namesrvAddr = 192.168.1.1:9876;192.168.1.2:9876
listenPort = 10911

# 存储配置
storePathRootDir = /data/rocketmq/store
storePathCommitLog = /data/rocketmq/store/commitlog

# 刷盘配置
flushDiskType = ASYNC_FLUSH

Broker-B 配置(broker-b.properties)

# 基础配置
brokerClusterName = DefaultCluster
brokerName = broker-b
brokerId = 0
namesrvAddr = 192.168.1.1:9876;192.168.1.2:9876
listenPort = 10911

# 存储配置
storePathRootDir = /data/rocketmq/store
storePathCommitLog = /data/rocketmq/store/commitlog

# 刷盘配置
flushDiskType = ASYNC_FLUSH

启动命令

# 在机器 A 上启动
nohup sh bin/mqbroker -c conf/broker-a.properties &

# 在机器 B 上启动
nohup sh bin/mqbroker -c conf/broker-b.properties &

优缺点

优点

  • 配置简单,易于维护
  • 所有节点均可写入,吞吐量高
  • 单节点故障不影响其他节点

缺点

  • 节点宕机期间消息不可用
  • 机器故障可能导致消息丢失
  • 不适合对可靠性要求高的场景

多 Master 多 Slave 部署

多 Master 多 Slave 架构是生产环境常用的部署方式,每个 Master 配备一个或多个 Slave 节点。

异步复制模式

Master 收到消息后立即返回,异步复制到 Slave。

Master 配置

brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
brokerRole = ASYNC_MASTER
namesrvAddr = 192.168.1.1:9876;192.168.1.2:9876
listenPort = 10911

# 刷盘配置
flushDiskType = ASYNC_FLUSH

# 主从同步配置
haListenPort = 10912
haMasterAddress = 192.168.1.10:10912

Slave 配置

brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 1
brokerRole = SLAVE
namesrvAddr = 192.168.1.1:9876;192.168.1.2:9876
listenPort = 10911

# 主从同步配置
haListenPort = 10912
haMasterAddress = 192.168.1.10:10912

特点

  • Master 写入成功即返回,性能高
  • Slave 异步复制,有短暂延迟
  • Master 故障可能丢失少量未同步的消息

同步双写模式

Master 收到消息后同步写入 Slave,两者都成功才返回。

Master 配置

brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
brokerRole = SYNC_MASTER
namesrvAddr = 192.168.1.1:9876;192.168.1.2:9876
listenPort = 10911

# 刷盘配置
flushDiskType = SYNC_FLUSH

# 主从同步配置
haListenPort = 10912

Slave 配置

brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 1
brokerRole = SLAVE
namesrvAddr = 192.168.1.1:9876;192.168.1.2:9876
listenPort = 10911

# 主从同步配置
haListenPort = 10912
haMasterAddress = 192.168.1.10:10912

特点

  • Master 和 Slave 同时写入成功才返回
  • 数据不丢失,可靠性高
  • 性能相对较低,延迟增加

两种模式对比

特性异步复制同步双写
性能
可靠性中(可能丢失少量消息)高(不丢消息)
延迟
适用场景允许少量丢失不允许丢失

Controller 模式(自动主从切换)

RocketMQ 5.x 引入了 Controller 模式,支持 Broker 主从自动切换,实现故障自动转移。

架构图

Controller 部署

Controller 提供选主能力,需要部署 3 个及以上节点(遵循 Raft 多数派协议)。

方式一:嵌入 NameServer 部署

在 NameServer 配置文件中添加 Controller 配置:

# namesrv.conf

# 开启 Controller 功能
enableControllerInNamesrv = true

# DLedger Raft Group 配置
controllerDLegerGroup = controller-group
controllerDLegerPeers = n0-192.168.1.1:9877;n1-192.168.1.2:9877;n2-192.168.1.3:9877
controllerDLegerSelfId = n0

# Controller 存储路径(重要,不可删除)
controllerStorePath = /data/rocketmq/controller

# 是否可以从 SyncStateSet 以外选举 Master
enableElectUncleanMaster = false

# Broker 角色变更时是否通知
notifyBrokerRoleChanged = true

启动 NameServer:

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

方式二:独立部署 Controller

# controller.conf
controllerDLegerGroup = controller-group
controllerDLegerPeers = n0-192.168.1.1:9877;n1-192.168.1.2:9877;n2-192.168.1.3:9877
controllerDLegerSelfId = n0
controllerStorePath = /data/rocketmq/controller

启动 Controller:

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

重要参数说明

参数说明
enableControllerInNamesrvNameServer 是否开启 Controller 功能
controllerDLegerGroupDLedger Raft Group 名称
controllerDLegerPeersController 集群节点信息
controllerDLegerSelfId当前节点 ID
controllerStorePathController 日志存储路径
enableElectUncleanMaster是否允许从同步集合外选举 Master

Broker 配置

在 Controller 模式下,Broker 需要配置以下参数:

# broker.conf

# 开启 Controller 模式
enableControllerMode = true

# Controller 地址
controllerAddr = 192.168.1.1:9877;192.168.1.2:9877;192.168.1.3:9877

# NameServer 地址
namesrvAddr = 192.168.1.1:9876;192.168.1.2:9876

# 同步副本数
inSyncReplicas = 2
minInSyncReplicas = 1

# 消息需要复制到所有同步副本才返回成功
allAckInSyncStateSet = true

# Slave 跟不上 Master 的最大时间间隔
haMaxTimeSlaveNotCatchup = 15000

关键配置参数

参数默认值说明
enableControllerModefalseController 模式总开关
controllerAddr-Controller 地址,分号分隔
syncBrokerMetadataPeriod5000向 Controller 同步信息的间隔
checkSyncStateSetPeriod5000检查同步状态集合的间隔
haMaxTimeSlaveNotCatchup15000Slave 最大落后时间(ms)
allAckInSyncStateSetfalse消息是否需要复制到所有同步副本
inSyncReplicas1需保持同步的副本数
minInSyncReplicas1最小同步副本数

启动 Broker

Controller 模式下,Broker 无需指定 brokerId 和 brokerRole,由 Controller 自动分配:

nohup sh bin/mqbroker -c conf/broker.conf &

故障切换流程

升级注意事项

从传统 Master-Slave 架构升级到 Controller 模式:

  1. 升级 NameServer:直接升级,无兼容性问题
  2. 升级 Broker
    • 停止主、备 Broker
    • 确保主、备 CommitLog 对齐
    • 升级后重启

注意:如果主备 CommitLog 不对齐,需要先启动原 Master,再启动原 Slave,否则可能因数据截断丢失消息。

NameServer 集群部署

NameServer 是无状态设计,各节点之间不通信,可以随意扩展。

推荐部署方案

配置客户端连接

// 设置多个 NameServer 地址
producer.setNamesrvAddr("192.168.1.1:9876;192.168.1.2:9876;192.168.1.3:9876");
consumer.setNamesrvAddr("192.168.1.1:9876;192.168.1.2:9876;192.168.1.3:9876");

客户端寻址方式

方式说明优缺点
代码指定直接设置 NamesrvAddr简单,但修改需重启
环境变量设置 NAMESRV_ADDR灵活,运维方便
HTTP 服务从 HTTP 服务获取最灵活,支持动态更新

HTTP 寻址示例

// 设置 HTTP 寻址地址
System.setProperty("rocketmq.namesrv.domain", "http://namesrv.example.com");
System.setProperty("rocketmq.namesrv.domain.subgroup", "nsaddr");

生产环境部署建议

硬件配置

组件CPU内存磁盘网络
NameServer4 核8 GB50 GB SSD千兆网卡
Broker(Master)16 核32 GB500 GB+ SSD万兆网卡
Broker(Slave)16 核32 GB500 GB+ SSD万兆网卡
Controller4 核8 GB50 GB SSD千兆网卡

网络规划

端口规划

端口服务说明
9876NameServer路由服务端口
10911Broker客户端连接端口
10912BrokerHA 端口(主从同步)
10909BrokerHA 端口(备用)
8081ProxygRPC 端口
9877ControllerDLedger 端口

高可用部署清单

  • NameServer 至少部署 2 个节点
  • Broker 采用 Master-Slave 架构
  • 开启同步刷盘或同步复制
  • 配置消息重试和死信队列
  • 部署监控系统(Prometheus + Grafana)
  • 配置告警规则
  • 定期备份配置文件
  • 制定故障恢复预案

常见问题

1. Broker 无法注册到 NameServer

问题:Broker 启动后无法注册到 NameServer

排查步骤

# 检查网络连通性
telnet 192.168.1.1 9876

# 检查 NameServer 是否启动
ps -ef | grep namesrv

# 查看 Broker 日志
tail -f ~/logs/rocketmqlogs/broker.log

解决方案

  • 检查防火墙配置
  • 确认 NameServer 地址配置正确
  • 检查 Broker 的 brokerIP1 配置

2. 主从同步延迟

问题:Slave 节点同步落后 Master 较多

排查步骤

# 查看主从同步状态
sh bin/mqadmin brokerStatus -n localhost:9876 -b broker-a

# 查看主从延迟
sh bin/mqadmin clusterList -n localhost:9876

解决方案

  • 检查网络带宽
  • 优化磁盘 IO 性能
  • 调整 HA 相关参数

3. Controller 选主失败

问题:Controller 集群无法选出 Leader

排查步骤

# 查看 Controller 日志
tail -f ~/logs/rocketmqlogs/controller.log

# 检查 Raft 节点配置
# 确认 controllerDLegerPeers 配置正确

解决方案

  • 确保多数派节点存活
  • 检查节点间网络连通性
  • 确认配置参数正确

小结

本章介绍了 RocketMQ 的集群部署方案:

  1. 单 Master:简单但不可靠,仅用于测试
  2. 多 Master:高性能但可能丢失消息
  3. 多 Master 多 Slave:高可用架构,生产环境推荐
  4. Controller 模式:自动故障转移,RocketMQ 5.x 推荐方案
  5. 部署建议:硬件、网络、端口规划

选择合适的部署架构是保证消息系统稳定运行的基础。

延伸阅读