云计算百科
云计算领域专业知识百科平台

RocketMQ 集群介绍

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 集群部署步骤
  • 环境准备:3 台服务器(192.168.1.12/13/14),已安装 RocketMQ,启动 NameServer 集群。
  • 配置文件分发:将上述 3 个配置文件分别放到对应节点的 conf/ 目录。
  • 启动集群(所有节点依次执行):# 节点 1
    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 &

  • 验证集群状态:# 查看 Dledger 节点角色
    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 投票核心规则(防脑裂关键)
  • 任期优先:高任期节点拒绝低任期节点的投票请求;
  • 日志完整性:仅投票给日志比自己新的 Candidate(保证数据一致性);
  • 多数票规则:必须获得 > N/2 节点投票才能成为 Leader(3 节点需 2 票,5 节点需 3 票);
  • 单任期单 Leader:同一任期内仅能有一个 Leader。
  • 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 防脑裂核心机制

  • 任期机制:每个节点维护「任期号」,高任期节点拒绝低任期节点的请求,分区恢复后旧 Leader 自动降级;
  • 多数票规则:网络分区后,只有包含多数节点的子集群能选出 Leader,其他子集群无法选举;
  • 日志校验:Candidate 需日志足够新才能获得投票,避免数据不一致的节点成为 Leader;
  • 心跳检测:Leader 定期发送心跳,Follower 超时未收到则触发选举,保证 Leader 唯一性。

  • 六、生产环境最佳实践

    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. 关键运维建议

  • NameServer 集群:至少 2 节点,无状态部署,无需主从;
  • Dledger 节点:
    • 优先选择奇数节点(3/5),避免偶数节点导致投票平局;
    • 同地域部署(跨可用区),避免跨地域网络延迟;
    • 存储目录使用独立磁盘(SSD 最佳),避免 IO 竞争;
  • 监控核心指标:
    • DLedger 节点角色(Leader/Follower);
    • 选举次数(频繁选举说明网络不稳定);
    • 日志复制延迟(Leader 与 Follower 日志索引差);
    • 消息堆积量(Leader 宕机后可能短暂堆积);
  • 灾备演练:定期手动关闭 Leader 节点,验证自动选主和业务恢复能力。

  • 七、总结

    核心关键点

  • 集群选型:核心业务优先选择 Dledger 3/5 节点集群(自动高可用、防脑裂),中小业务可先用传统主从(降低成本);
  • 选主机制:传统主从无自动选主,Dledger 基于 Raft 协议实现「多数票选举 + 任期机制」,保证 Leader 唯一性;
  • 脑裂防护:Dledger 依靠 Raft 协议从底层避免脑裂,传统主从需人工规范操作+VIP 仲裁;
  • 配置核心:Dledger 集群需重点配置 dLegerPeers 和 dLegerSelfId,保证节点列表与实际部署一致;
  • 运维重点:监控 DLedger 选举次数和日志复制延迟,定期演练故障恢复。
  • 最终建议

    • 测试环境:单 Master 或多 Master;
    • 中小生产:传统主从(SYNC_MASTER + Slave)+ VIP 漂移;
    • 核心生产:Dledger 3 节点集群(强烈推荐);
    • 超大规模生产:Dledger 5 节点集群 + 多组 Broker 水平扩展。
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » RocketMQ 集群介绍
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!