RocketMQ 集群介绍
九、RocketMQ 集群部署与高可用机制
RocketMQ 集群的核心价值在于通过多节点部署实现高可用、高吞吐和数据一致性,其集群设计围绕「Broker 主从」和「NameServer 无状态集群」展开,核心分为传统主从模式和基于 Raft 协议的 Dledger 自动容灾模式。本文详细讲解集群部署方式、选主机制、核心配置、优缺点及脑裂防护方案。
一、集群部署模式(增强版)
1. 基础部署模式对比
| 单 Master | 1 个 Broker(Master)+ 1+ NameServer | 部署最简,无冗余 | 0(宕机即不可用) | – | 本地测试、功能验证 |
| 多 Master | N 个 Broker(均为 Master)+ 1+ NameServer | 写性能最高,无同步开销 | 部分可用(单节点宕机则对应队列不可用) | 弱(节点宕机丢失未持久化数据) | 非核心业务、临时测试 |
| 多 Master + 多 Slave(传统主从) | 每个 Master 对应 1+ Slave + 1+ NameServer | 主写从读,需手动切换 | 高(需人工介入恢复) | 异步复制:弱同步双写:强 | 中小生产环境、可接受手动运维 |
| Dledger 集群(Raft 模式) | 3/5 个 Broker 组成 Raft Group + 1+ NameServer | 自动选主、自动故障转移 | 极高(秒级自动恢复) | 强(Quorum 写入确认) | 核心生产环境、金融级场景 |
2. 传统主从模式(Master-Slave)详细配置
2.1 核心配置说明(broker.conf)
传统主从模式需为每个 Master/Slave 配置独立文件,核心配置项如下:
# ===================== 公共配置(所有节点)=====================
brokerClusterName=MyRocketMQCluster # 集群名称(所有节点必须一致)
brokerId=0 # Master 为 0,Slave 为 1/2/3…(数字越大优先级越低)
listenPort=10911 # Broker 服务端口(Slave 可与 Master 不同)
namesrvAddr=192.168.1.10:9876;192.168.1.11:9876 # NameServer 集群地址
storePathRootDir=/data/rocketmq/store # 消息存储根目录
storePathCommitLog=/data/rocketmq/store/commitlog # 提交日志存储路径
autoCreateTopicEnable=true # 自动创建 Topic(生产建议关闭)
deleteWhen=04 # 凌晨 4 点清理过期消息
fileReservedTime=72 # 消息保留时长(小时)
mapedFileSizeCommitLog=1073741824 # CommitLog 文件大小(默认 1GB)
# ===================== Master 节点专属配置 =====================
brokerName=broker-a # 主从节点需同名(标识同一组)
brokerRole=SYNC_MASTER # 主节点角色:SYNC_MASTER(同步双写)/ASYNC_MASTER(异步复制)
flushDiskType=SYNC_FLUSH # 刷盘策略:SYNC_FLUSH(同步刷盘)/ASYNC_FLUSH(异步刷盘)
# ===================== Slave 节点专属配置 =====================
brokerName=broker-a # 必须与对应 Master 一致
brokerId=1 # Slave 标识(非 0 即可)
brokerRole=SLAVE # 从节点角色
flushDiskType=ASYNC_FLUSH # Slave 建议异步刷盘
pullMessageThreadPoolNums=32 # 从节点拉取线程数(优化读性能)
2.2 传统主从部署步骤(以 1 Master + 1 Slave 为例)
环境准备
- 两台服务器(如 192.168.1.10、192.168.1.11),均安装 RocketMQ
- 配置 JAVA_HOME,关闭防火墙/SELINUX
- 提前启动 NameServer 集群(至少 2 节点):# 启动 NameServer(所有节点执行)
nohup sh bin/mqnamesrv &
# 验证 NameServer 启动
jps | grep NamesrvStartup
Master 节点配置与启动
# 1. 编辑 Master 配置文件
vi conf/broker-a-master.conf # 内容如上 Master 配置
# 2. 启动 Master
nohup sh bin/mqbroker -c conf/broker-a-master.conf &
# 3. 验证 Master 注册(NameServer 节点执行)
sh bin/mqadmin clusterList -n 192.168.1.10:9876
Slave 节点配置与启动
# 1. 编辑 Slave 配置文件
vi conf/broker-a-slave.conf # 内容如上 Slave 配置
# 2. 启动 Slave
nohup sh bin/mqbroker -c conf/broker-a-slave.conf &
# 3. 验证主从关系
sh bin/mqadmin clusterList -n 192.168.1.10:9876 # 可看到 broker-a 包含 Master/Slave
2.3 传统主从故障恢复(手动切换)
当 Master 宕机时,需手动将 Slave 提升为 Master:
# 1. 停止故障 Master 节点(若未宕机)
sh bin/mqshutdown broker
# 2. 修改 Slave 配置文件
vi conf/broker-a-slave.conf
brokerId=0 # 改为 0(Master 标识)
brokerRole=SYNC_MASTER # 改为主节点角色
# 3. 重启 Slave 节点
sh bin/mqshutdown broker
nohup sh bin/mqbroker -c conf/broker-a-slave.conf &
# 4. 通知客户端更新路由(可选,客户端会自动从 NameServer 拉取新路由)
3. Dledger 集群模式(推荐生产)
3.1 Dledger 核心原理
Dledger 是 RocketMQ 基于 Raft 协议实现的分布式日志复制框架,核心解决传统主从「手动切换」和「数据不一致」问题,其核心特性:
- 节点角色:Leader(主)、Follower(从)、Candidate(候选者)
- 选主规则:需获得超过半数节点投票(N/2 + 1)
- 数据复制:Leader 接收写请求后,同步日志到 Follower,需多数节点确认后才返回成功
- 故障转移:Leader 宕机后,Follower 自动触发选举,秒级选出新 Leader
3.2 Dledger 集群配置(3 节点示例)
核心配置文件(dledger-broker-n0.conf,节点 1)
# ===================== 基础配置 =====================
brokerClusterName=DledgerCluster
brokerName=broker-dledger # 所有节点必须同名
brokerId=0 # Dledger 模式下 brokerId 无意义,仅需唯一
listenPort=10911
namesrvAddr=192.168.1.10:9876;192.168.1.11:9876
storePathRootDir=/data/rocketmq/dledger/store
storePathCommitLog=/data/rocketmq/dledger/store/commitlog
# ===================== Dledger 核心配置 =====================
enableDLegerCommitLog=true # 开启 Dledger 模式(核心开关)
dLegerGroup=broker-dledger-group # Raft Group 名称(所有节点一致)
# 集群节点列表:格式 节点ID-IP:端口(端口为 Dledger 通信端口,非 Broker 端口)
dLegerPeers=n0-192.168.1.12:40911;n1-192.168.1.13:40911;n2-192.168.1.14:40911
dLegerSelfId=n0 # 当前节点 ID(每个节点不同:n0/n1/n2)
dLegerElectorType=RAFT # 选举类型(固定为 RAFT)
# ===================== 性能配置 =====================
sendMessageThreadPoolNums=16 # 发送线程数
pullMessageThreadPoolNums=32 # 拉取线程数
flushDiskType=ASYNC_FLUSH # Dledger 模式下建议异步刷盘(由 Raft 保证一致性)
节点 2(dledger-broker-n1.conf)关键差异
dLegerSelfId=n1 # 节点 ID 改为 n1
listenPort=10921 # Broker 端口可不同(避免冲突)
节点 3(dledger-broker-n2.conf)关键差异
dLegerSelfId=n2 # 节点 ID 改为 n2
listenPort=10931 # Broker 端口可不同
3.3 Dledger 集群部署步骤
nohup sh bin/mqbroker -c conf/dledger-broker-n0.conf &
# 节点 2
nohup sh bin/mqbroker -c conf/dledger-broker-n1.conf &
# 节点 3
nohup sh bin/mqbroker -c conf/dledger-broker-n2.conf &
sh bin/mqadmin getBrokerStatus -n 192.168.1.10:9876 -b 192.168.1.12:10911
# 输出示例:role=LEADER 或 FOLLOWER
# 查看集群整体状态
sh bin/mqadmin clusterList -n 192.168.1.10:9876
二、集群选主机制(深度解析)
1. 传统主从模式:无自动选主
传统主从模式无内置选主逻辑,Master 身份由配置文件 brokerId=0 和 brokerRole=SYNC_MASTER/ASYNC_MASTER 固定:
- 启动时,Slave 会主动连接 Master 同步数据,Master 无需「选举」;
- Master 宕机后,Slave 仍为 Slave 角色,需人工修改配置将 Slave 改为 Master;
- 客户端仅向 Master 写消息,Slave 仅提供读能力,无自动切换逻辑。
2. Dledger 集群:Raft 选主流程(完整步骤)
Dledger 选主基于 Raft 协议,核心分为「初始选举」和「故障重选」两个阶段,全程自动执行:
2.1 初始选举流程
#mermaid-svg-evdKKBGLbze9Teoe{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-evdKKBGLbze9Teoe .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-evdKKBGLbze9Teoe .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-evdKKBGLbze9Teoe .error-icon{fill:#552222;}#mermaid-svg-evdKKBGLbze9Teoe .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-evdKKBGLbze9Teoe .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-evdKKBGLbze9Teoe .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-evdKKBGLbze9Teoe .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-evdKKBGLbze9Teoe .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-evdKKBGLbze9Teoe .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-evdKKBGLbze9Teoe .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-evdKKBGLbze9Teoe .marker{fill:#333333;stroke:#333333;}#mermaid-svg-evdKKBGLbze9Teoe .marker.cross{stroke:#333333;}#mermaid-svg-evdKKBGLbze9Teoe svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-evdKKBGLbze9Teoe p{margin:0;}#mermaid-svg-evdKKBGLbze9Teoe .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-evdKKBGLbze9Teoe .cluster-label text{fill:#333;}#mermaid-svg-evdKKBGLbze9Teoe .cluster-label span{color:#333;}#mermaid-svg-evdKKBGLbze9Teoe .cluster-label span p{background-color:transparent;}#mermaid-svg-evdKKBGLbze9Teoe .label text,#mermaid-svg-evdKKBGLbze9Teoe span{fill:#333;color:#333;}#mermaid-svg-evdKKBGLbze9Teoe .node rect,#mermaid-svg-evdKKBGLbze9Teoe .node circle,#mermaid-svg-evdKKBGLbze9Teoe .node ellipse,#mermaid-svg-evdKKBGLbze9Teoe .node polygon,#mermaid-svg-evdKKBGLbze9Teoe .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-evdKKBGLbze9Teoe .rough-node .label text,#mermaid-svg-evdKKBGLbze9Teoe .node .label text,#mermaid-svg-evdKKBGLbze9Teoe .image-shape .label,#mermaid-svg-evdKKBGLbze9Teoe .icon-shape .label{text-anchor:middle;}#mermaid-svg-evdKKBGLbze9Teoe .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-evdKKBGLbze9Teoe .rough-node .label,#mermaid-svg-evdKKBGLbze9Teoe .node .label,#mermaid-svg-evdKKBGLbze9Teoe .image-shape .label,#mermaid-svg-evdKKBGLbze9Teoe .icon-shape .label{text-align:center;}#mermaid-svg-evdKKBGLbze9Teoe .node.clickable{cursor:pointer;}#mermaid-svg-evdKKBGLbze9Teoe .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-evdKKBGLbze9Teoe .arrowheadPath{fill:#333333;}#mermaid-svg-evdKKBGLbze9Teoe .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-evdKKBGLbze9Teoe .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-evdKKBGLbze9Teoe .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-evdKKBGLbze9Teoe .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-evdKKBGLbze9Teoe .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-evdKKBGLbze9Teoe .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-evdKKBGLbze9Teoe .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-evdKKBGLbze9Teoe .cluster text{fill:#333;}#mermaid-svg-evdKKBGLbze9Teoe .cluster span{color:#333;}#mermaid-svg-evdKKBGLbze9Teoe div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-evdKKBGLbze9Teoe .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-evdKKBGLbze9Teoe rect.text{fill:none;stroke-width:0;}#mermaid-svg-evdKKBGLbze9Teoe .icon-shape,#mermaid-svg-evdKKBGLbze9Teoe .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-evdKKBGLbze9Teoe .icon-shape p,#mermaid-svg-evdKKBGLbze9Teoe .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-evdKKBGLbze9Teoe .icon-shape rect,#mermaid-svg-evdKKBGLbze9Teoe .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-evdKKBGLbze9Teoe .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-evdKKBGLbze9Teoe .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-evdKKBGLbze9Teoe :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
是
否
是
否
所有节点启动
重置超时器,保持 Follower
是否收到 Leader 心跳?
转为 Candidate,发起投票请求
向所有节点发送 VoteRequest(包含自身任期、日志索引)
是否获得半数以上投票?
转为 Leader,定期发送心跳(默认 200ms)
等待超时,重新发起投票
接收写请求,同步日志到 Follower
2.2 故障重选流程(Leader 宕机)
#mermaid-svg-8mRkHECSyd8fppTA{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8mRkHECSyd8fppTA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8mRkHECSyd8fppTA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8mRkHECSyd8fppTA .error-icon{fill:#552222;}#mermaid-svg-8mRkHECSyd8fppTA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8mRkHECSyd8fppTA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8mRkHECSyd8fppTA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8mRkHECSyd8fppTA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8mRkHECSyd8fppTA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8mRkHECSyd8fppTA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8mRkHECSyd8fppTA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8mRkHECSyd8fppTA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8mRkHECSyd8fppTA .marker.cross{stroke:#333333;}#mermaid-svg-8mRkHECSyd8fppTA svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8mRkHECSyd8fppTA p{margin:0;}#mermaid-svg-8mRkHECSyd8fppTA .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-8mRkHECSyd8fppTA .cluster-label text{fill:#333;}#mermaid-svg-8mRkHECSyd8fppTA .cluster-label span{color:#333;}#mermaid-svg-8mRkHECSyd8fppTA .cluster-label span p{background-color:transparent;}#mermaid-svg-8mRkHECSyd8fppTA .label text,#mermaid-svg-8mRkHECSyd8fppTA span{fill:#333;color:#333;}#mermaid-svg-8mRkHECSyd8fppTA .node rect,#mermaid-svg-8mRkHECSyd8fppTA .node circle,#mermaid-svg-8mRkHECSyd8fppTA .node ellipse,#mermaid-svg-8mRkHECSyd8fppTA .node polygon,#mermaid-svg-8mRkHECSyd8fppTA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8mRkHECSyd8fppTA .rough-node .label text,#mermaid-svg-8mRkHECSyd8fppTA .node .label text,#mermaid-svg-8mRkHECSyd8fppTA .image-shape .label,#mermaid-svg-8mRkHECSyd8fppTA .icon-shape .label{text-anchor:middle;}#mermaid-svg-8mRkHECSyd8fppTA .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8mRkHECSyd8fppTA .rough-node .label,#mermaid-svg-8mRkHECSyd8fppTA .node .label,#mermaid-svg-8mRkHECSyd8fppTA .image-shape .label,#mermaid-svg-8mRkHECSyd8fppTA .icon-shape .label{text-align:center;}#mermaid-svg-8mRkHECSyd8fppTA .node.clickable{cursor:pointer;}#mermaid-svg-8mRkHECSyd8fppTA .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8mRkHECSyd8fppTA .arrowheadPath{fill:#333333;}#mermaid-svg-8mRkHECSyd8fppTA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8mRkHECSyd8fppTA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8mRkHECSyd8fppTA .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8mRkHECSyd8fppTA .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8mRkHECSyd8fppTA .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8mRkHECSyd8fppTA .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8mRkHECSyd8fppTA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8mRkHECSyd8fppTA .cluster text{fill:#333;}#mermaid-svg-8mRkHECSyd8fppTA .cluster span{color:#333;}#mermaid-svg-8mRkHECSyd8fppTA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8mRkHECSyd8fppTA .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8mRkHECSyd8fppTA rect.text{fill:none;stroke-width:0;}#mermaid-svg-8mRkHECSyd8fppTA .icon-shape,#mermaid-svg-8mRkHECSyd8fppTA .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8mRkHECSyd8fppTA .icon-shape p,#mermaid-svg-8mRkHECSyd8fppTA .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8mRkHECSyd8fppTA .icon-shape rect,#mermaid-svg-8mRkHECSyd8fppTA .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8mRkHECSyd8fppTA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8mRkHECSyd8fppTA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8mRkHECSyd8fppTA :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
是
否
Leader 宕机,停止发送心跳
Follower 选举超时器触发
Follower 转为 Candidate,自增任期,发起投票
节点间投票,遵循 Raft 投票规则
是否有节点获得半数以上投票?
新 Leader 产生,接管写服务
重新投票(任期自增)
新 Leader 同步日志到剩余 Follower
客户端从 NameServer 获取新 Leader 地址,恢复写服务
2.3 Raft 投票核心规则(防脑裂关键)
3. 选主关键配置项
| dLegerElectorType | RAFT | 选举类型(固定为 RAFT) | 不可修改 |
| dledger.election.timeout.ms | 1000 | 选举超时时间(Follower 未收到心跳触发选举) | 生产建议 1000-3000ms |
| dledger.heartbeat.interval.ms | 200 | Leader 心跳发送间隔 | 建议 200-500ms(过短增加网络开销) |
| dledger.commit.timeout.ms | 2000 | 日志提交超时时间 | 建议 1000-3000ms |
| dledger.max.wait.leader.ms | 60000 | 最大等待 Leader 时间 | 保持默认即可 |
三、核心配置项详解(按模块分类)
1. 集群基础配置
| brokerClusterName | 集群名称(标识同一集群) | MyRocketMQCluster | 所有节点保持一致 |
| brokerName | 主从组/DLedger 组名称 | broker-a | 同一组节点必须一致 |
| brokerId | Master/Slave 标识 | Master=0,Slave=1+ | Dledger 模式下无意义 |
| namesrvAddr | NameServer 集群地址 | 192.168.1.10:9876;192.168.1.11:9876 | 至少配置 2 个,用分号分隔 |
| listenPort | Broker 服务端口 | 10911 | 不同节点可不同,避免端口冲突 |
2. Dledger 专属配置
| enableDLegerCommitLog | 开启 Dledger 模式 | true/false | 生产必须设为 true |
| dLegerGroup | Raft Group 名称 | broker-dledger-group | 同一 DLedger 集群必须一致 |
| dLegerPeers | 集群节点列表 | n0-192.168.1.12:40911;n1-192.168.1.13:40911 | 端口建议 40911/40912 等,避免冲突 |
| dLegerSelfId | 当前节点 ID | n0/n1/n2 | 每个节点唯一,与 peers 中的 ID 对应 |
3. 性能与一致性配置
| brokerRole | 节点角色 | SYNC_MASTER/ASYNC_MASTER/SLAVE | 传统主从:Master 用 SYNC_MASTER;Dledger 模式无需配置 |
| flushDiskType | 刷盘策略 | SYNC_FLUSH/ASYNC_FLUSH | 传统主从 Master:SYNC_FLUSH;Dledger 模式:ASYNC_FLUSH |
| fileReservedTime | 消息保留时长 | 72(小时) | 核心业务可设为 168(7 天),非核心设为 24 |
| mapedFileSizeCommitLog | CommitLog 文件大小 | 1073741824(1GB) | 保持默认,过大易导致磁盘 IO 卡顿 |
四、集群优缺点(增强版)
1. 传统主从集群(多 Master + 多 Slave)
优点
- 部署简单:配置少,运维门槛低;
- 性能可控:主写从读,可灵活调整 Slave 数量提升读性能;
- 资源开销低:无 Raft 协议的日志复制和投票开销;
- 兼容性好:支持所有 RocketMQ 版本,无版本限制。
缺点
- 无自动选主:Master 宕机需人工切换,恢复时间长(分钟级);
- 脑裂风险:网络分区时,Slave 被手动提升为 Master,原 Master 恢复后出现双 Master;
- 数据一致性弱:异步复制模式下,Master 宕机可能丢失未同步数据;
- 运维成本高:需人工监控节点状态,故障时需及时介入。
2. Dledger 集群(Raft 模式)
优点
- 自动选主/故障转移:Leader 宕机后秒级选出新 Leader,无需人工干预;
- 强数据一致性:基于 Quorum 写入规则,仅当多数节点确认日志后才返回成功;
- 防脑裂:Raft 协议的「多数票规则」从根本上避免脑裂;
- 高可用:3 节点集群可容忍 1 节点故障,5 节点可容忍 2 节点故障;
- 运维简化:无需手动切换主从,降低人工操作风险。
缺点
- 资源开销高:
- 存储开销:每份数据需存储 3/5 副本(传统主从仅 2 副本);
- 网络开销:Leader 需同步日志到 Follower,投票和心跳增加网络流量;
- 部署复杂度高:需配置 Raft 节点列表、端口等,配置错误易导致集群不可用;
- 最小节点要求:至少 3 节点(2 节点无法满足多数票规则),小型业务成本高;
- 网络敏感:Raft 协议对网络延迟敏感(>10ms 可能导致选举不稳定),不适合跨地域部署;
- 版本限制:仅支持 RocketMQ 4.5+ 版本。
五、脑裂问题分析与防护
1. 脑裂定义
脑裂是指集群因网络分区导致「一个集群被拆分为多个独立子集群」,每个子集群各自选出 Leader,导致数据不一致、重复写入等问题。
2. 不同模式下的脑裂风险
| 传统主从 | 高风险 | 网络分区后,人工误操作将 Slave 提升为 Master,原 Master 恢复后形成双 Master | 1. 提升 Slave 前先确认原 Master 彻底宕机;2. 采用 VIP 漂移+仲裁机制(如 ZooKeeper 确认);3. 禁止跨机房部署传统主从 |
| Dledger 集群 | 无风险 | Raft 协议的「多数票规则」:1. 网络分区后,仅能有一个子集群满足「多数节点」条件,才能选出 Leader;2. 分区恢复后,旧 Leader 发现任期更低,自动转为 Follower | 1. 配置奇数节点(3/5);2. 合理设置选举超时时间(1000-3000ms);3. 避免跨高延迟网络部署 |
3. Dledger 防脑裂核心机制
六、生产环境最佳实践
1. 集群规划建议
| 小型业务(QPS < 1w) | Dledger 3 节点 | 3 台 8C16G 服务器,单盘 > 200GB | 异步刷盘,消息保留 24 小时 |
| 中型业务(1w < QPS < 10w) | Dledger 3 节点 + 多组 Broker | 3 节点 DLedger 为一组,部署 2-3 组 | 每组独立 Raft Group,NameServer 2 节点 |
| 大型业务(QPS > 10w) | Dledger 5 节点 + 多组 Broker | 5 节点 DLedger 为一组,部署 3+ 组 | 跨可用区部署(同地域),开启消息轨迹 |
2. 关键运维建议
- 优先选择奇数节点(3/5),避免偶数节点导致投票平局;
- 同地域部署(跨可用区),避免跨地域网络延迟;
- 存储目录使用独立磁盘(SSD 最佳),避免 IO 竞争;
- DLedger 节点角色(Leader/Follower);
- 选举次数(频繁选举说明网络不稳定);
- 日志复制延迟(Leader 与 Follower 日志索引差);
- 消息堆积量(Leader 宕机后可能短暂堆积);
七、总结
核心关键点
最终建议
- 测试环境:单 Master 或多 Master;
- 中小生产:传统主从(SYNC_MASTER + Slave)+ VIP 漂移;
- 核心生产:Dledger 3 节点集群(强烈推荐);
- 超大规模生产:Dledger 5 节点集群 + 多组 Broker 水平扩展。
网硕互联帮助中心





评论前必须登录!
注册