RocketMQ 5.2.0 集群Dledger的扩展调研/实践

前段时间季度OKR任务 RocketMQ 集群的扩展(技术场景调研/文档/实践) 在上个季度已经完成了 清明节放假有时间总结一下 输出一下 从单机到集群的架构和原理探索 最后raft分布式一致性算法进行节点的同步和协作,看了看raft论文和其他分布式算法Paxos论文知识点 也比较有意思,目前只是搭建了3个节点 只能容许一个节点宕机 还是会出现不可用的现象,总比原来的单机好吧. 单机切换到集群过程 怎么切?未消费的数据怎么迁移?后面又遇到节点CPU 100%现象 怎么去解决?Dledger只是当前正好符合我们组内的需求 新的架构模式Controller集群 还是需要花时间去了解。

  • 最近在准备jlpt 日语N2考试 lslj4qcpwg.feishu.cn/docx/I4pKdH... ai相关技术都没时间学习 mcp manus等等 RocketMQ源码学习也没有时间了
  • RocketMQ 版本迭代是真的快 今天看了一眼已经是5.3.2 版本了 issue和feat也是挺多的。

前期调研 准备

集群方案

  • 集群部署的版本确定? 当前部署的单机版本是V4_9_3 rocketmq-4.9.3

单机master ASYNC_MASTER 异步刷盘

单机master broker.conf 配置信息 ASYNC_MASTER 异步刷盘

yaml 复制代码
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH

集群模式

  • 多组节点(集群)单副本模式? 一个集群内全部部署 Master 角色,不部署Slave 副本,例如2个Master或者3个Master
  • 多节点(集群)多副本模式-异步复制? 每个Master配置一个Slave,有多组 Master-Slave,HA采用异步复制方式,主备有短暂消息延迟(毫秒级)
  • 多节点(集群)多副本模式-同步双写? 每个Master配置一个Slave,有多对 Master-Slave,HA采用同步双写方式,即只有主备都写成功,才向应用返回成功
  • 2m-2s-async:2主2从异步刷盘(吞吐量较大,但是消息可能丢失),
  • 2m-2s-sync:2主2从同步刷盘(吞吐量会下降,但是消息更安全),
  • 2m-noslave:2主无从(单点故障),也可以直接配置broker.conf,进行单点环境配置。
  • dleger:是用来实现主从切换的。集群中的节点会基于Raft协议随机选举出一个leader,其他的就都是follower。通常正式环境都会采用这种方式来搭建集群。

github.com/apache/rock...

macbook pro 本地单机启动 mq

python 复制代码
 wget https://dist.apache.org/repos/dist/release/rocketmq/5.2.0/rocketmq-all-5.2.0-bin-release.zip
 unzip rocketmq-all-5.2.0-bin-release.zip
 sh ./bin/mqnamesrv
 sh bin/mqbroker -n localhost:9876

2主2从异步刷盘的集群

适用于对高可用性有要求,但对消息丢失容忍度较高的场景

  • 主从模式中分为Master和Slave两个角色,集群中可以有多个Master节点,一个Master节点可以有多个Slave节点。Master节点负责接收生产者发送的写入请求,将消息写入CommitLog文件,Slave节点会与Master节点建立连接,从Master节点同步消息数据(有同步复制和异步复制两种方式)。消费者可以从Master节点拉取消息,也可以从Slave节点拉取消息。
机器名 nemaeserver节点部署 broker 节点部署
25 nemaeserver broker-a, broker-b-s
20 nemaeserver broker-b,broker-a-s

25 机器

bash 复制代码
nohup ./mqnamesrv &
nohup bin/mqbroker -c conf/2m-2s-async/broker-a.properties &
nohup bin/mqbroker -c conf/2m-2s-async/broker-b-s.properties &

20 机器

bash 复制代码
nohup ./mqnamesrv &
nohup bin/mqbroker -c conf/2m-2s-async/broker-b.properties &
nohup bin/mqbroker -c conf/2m-2s-async/broker-a-s.properties >nohup2.out 2>&1 &

conf配置文件省略...........

  • 关闭2个master节点 测试 剩下两个 slave节点 发送消息直接异常 只有master节点能提供写的功能

sh bin/mqbroker -m 查看配置信息

yaml 复制代码
2024-10-25 18:02:12 INFO main - namesrvAddr=
2024-10-25 18:02:12 INFO main - listenPort=6888
2024-10-25 18:02:12 INFO main - brokerIP1=xxxxxx
2024-10-25 18:02:12 INFO main - recoverConcurrently=false
2024-10-25 18:02:12 INFO main - autoCreateTopicEnable=true
2024-10-25 18:02:12 INFO main - autoCreateSubscriptionGroup=true
2024-10-25 18:02:12 INFO main - msgTraceTopicName=RMQ_SYS_TRACE_TOPIC
2024-10-25 18:02:12 INFO main - traceTopicEnable=false
2024-10-25 18:02:12 INFO main - rejectTransactionMessage=false
2024-10-25 18:02:12 INFO main - fetchNameSrvAddrByDnsLookup=false
2024-10-25 18:02:12 INFO main - fetchNamesrvAddrByAddressServer=false
2024-10-25 18:02:12 INFO main - transactionTimeOut=6000
2024-10-25 18:02:12 INFO main - transactionCheckMax=15
2024-10-25 18:02:12 INFO main - transactionCheckInterval=30000
2024-10-25 18:02:12 INFO main - aclEnable=false
2024-10-25 18:02:12 INFO main - storePathRootDir=/root/store
2024-10-25 18:02:12 INFO main - storePathCommitLog=
2024-10-25 18:02:12 INFO main - storePathDLedgerCommitLog=
2024-10-25 18:02:12 INFO main - storePathEpochFile=
2024-10-25 18:02:12 INFO main - storePathBrokerIdentity=
2024-10-25 18:02:12 INFO main - disappearTimeAfterStart=-1
2024-10-25 18:02:12 INFO main - storeType=default
2024-10-25 18:02:12 INFO main - flushIntervalCommitLog=500
2024-10-25 18:02:12 INFO main - commitIntervalCommitLog=200
2024-10-25 18:02:12 INFO main - flushCommitLogTimed=true
2024-10-25 18:02:12 INFO main - deleteWhen=04
2024-10-25 18:02:12 INFO main - fileReservedTime=72
2024-10-25 18:02:12 INFO main - deleteFileBatchMax=10
2024-10-25 18:02:12 INFO main - maxTransferBytesOnMessageInMemory=262144
2024-10-25 18:02:12 INFO main - maxTransferCountOnMessageInMemory=32
2024-10-25 18:02:12 INFO main - maxTransferBytesOnMessageInDisk=65536
2024-10-25 18:02:12 INFO main - maxTransferCountOnMessageInDisk=8
2024-10-25 18:02:12 INFO main - accessMessageInMemoryMaxRatio=40
2024-10-25 18:02:12 INFO main - messageIndexEnable=true
2024-10-25 18:02:12 INFO main - messageIndexSafe=false
2024-10-25 18:02:12 INFO main - haMasterAddress=
2024-10-25 18:02:12 INFO main - brokerRole=ASYNC_MASTER
2024-10-25 18:02:12 INFO main - flushDiskType=ASYNC_FLUSH
2024-10-25 18:02:12 INFO main - cleanFileForciblyEnable=true
2024-10-25 18:02:12 INFO main - transientStorePoolEnable=false
2024-10-25 18:02:12 INFO main - dispatchFromSenderThread=false
2024-10-25 18:02:12 INFO main - wakeCommitWhenPutMessage=true
2024-10-25 18:02:12 INFO main - wakeFlushWhenPutMessage=false
2024-10-25 18:02:12 INFO main - enableCleanExpiredOffset=false
2024-10-25 18:02:12 INFO main - totalReplicas=1
2024-10-25 18:02:12 INFO main - inSyncReplicas=1
2024-10-25 18:02:12 INFO main - minInSyncReplicas=1
2024-10-25 18:02:12 INFO main - allAckInSyncStateSet=false
2024-10-25 18:02:12 INFO main - enableAutoInSyncReplicas=false
2024-10-25 18:02:12 INFO main - haFlowControlEnable=false
  • 缺点: master提供读写 slave只有备份的功能/读的功能 当masterdown了之后,从节点不会自动升级为master, slave备份了数据 需要手动进行节点切换(特别恶心 不如直接重启master) 没有自动切换的实现 从节点非常鸡肋 达不到我想到的高可用场景

记得修改JVM 内存大小 xms xmx=2g

bash 复制代码
nohup ./mqnamesrv &
nohup bin/mqbroker -c conf/2m-2s-async/broker-a.properties &
nohup bin/mqbroker -c conf/2m-2s-async/broker-b-s.properties &

Dledger搭建rokcetMQ高可用集群

适用于金融、电商等对数据一致性和系统可靠性有极高要求的业务场景。 高可用、高性能、高可靠

  • 为了解决主从架构下Slave不能自动切换为Master的问题,4.5版本之后提供了DLedger模式,使用Raft算法,如果Master节点出现故障,可以自动从Slave节点中选举出新的Master进行切换。
  • RocketMQ-on-DLedger Group 是指一组相同名称的 Broker,至少需要 3 个节点,通过 Raft 自动选举出一个 Leader,其余节点 作为 Follower,并在 Leader 和 Follower 之间复制数据以保证高可用。 RocketMQ-on-DLedger Group 能自动容灾切换,并保证数据一致。 RocketMQ-on-DLedger Group 是可以水平扩展的,也即可以部署任意多个 RocketMQ-on-DLedger Group 同时对外提供服务。
  • Dledger 模式下,一条消息会被复制到多个 Broker 节点上,因此同一条消息会出现在多个 Broker 中。这与传统的 RocketMQ 主从模式不同,它通过 Raft 协议提供了更强的一致性保障。
  • Dledger | RocketMQ
    • 数据复制:DLedger集群通过raft协 议来保证数据的一致性。在集群中,每个节点都维护一个相同的数据副本,以确保当某个节点出现故障时,数据不会丢失。
    • 容错性:DLedger集群具有很高的容错性。即使集群中的部分节点发生故障,只要集群中有大多数节点(即超过半数)仍在正常工作,整个集群将继续提供服务。
    • 高可用性:DLedger集群通过负载均衡和热备份等机制,确保在节点故障时能够快速切换到其他正常节点,提高整个系统的可用性。
    • 分布式锁:DLedger集群提供分布式锁功能,可以解决分布式系统中的资源争用问题,实现跨节点的资源同步。
    • 强一致性:DLedger集群通过使用Raft一致性协议,确保在多个副本节点之间同步数据,保证数据的强一致性。
    • 高性能:DLedger集群支持水平扩展,可以通过增加节点来提高系统的吞吐量和存储能力,以满足不断增长的业务需求。
  • 节点的部署需要是奇数 比如三台(它能够容忍1台机器down,active的机器是2>3/2 大于半数节点 2台其中一台会自动切换为master) 当2台机器down了 剩下的一台不会自动切换为master 。服务器成本问题 3台估计是能接受的极限了,高可用只能接受一台机器down 其他down 自动等重启/恢复 重新选举master
  • 相对于2m-2s-async 自动切换是最大的特点

存在问题

  1. 根据Raft算法的多数原则,集群至少有三个节点以上,在消息写入时,也需要大多数的Follower节点响应成功才能认为消息写入成功;
  2. Dledger模式下,进行消息写入的时候,使用的是openmessaging包中提供的接口,无法利用RocketMQ原生的存储和复制能力(比如非Dledger模式下使用暂存池方式写入);
  3. 存在两套日志复制流程(主从模式下一套、Dledger模式下一套),不统一;

深入理解架构原理

5.X 版本 Controller 集群主从模式 主节点down 从节点能够自动切换

    • 在主从部署模式下就具有自动切换Master的能力,5.0之前需要使用DLedger才可以;
    • 可以利用RocketMQ原生存储复制能力,并统一RocketMQ的存储和复制能力;

真的 没有什么是加一层解决不了的

RocketMQ 5.0对Broker选主相关的功能进行了抽离,放在Controller中,实现了在主从部署模式下就可以自动切换Master,Controller可以独立部署也可以嵌入在NameServer中部署。

独立部署下的Controller

嵌入NameServer中的部署图

Dledger 主要解决 数据一致性高可用性,通过 Raft 协议来保证多个 Broker 之间的数据同步和故障恢复。

Controller 则主要负责 集群管理,包括 Broker 的健康监控、负载均衡、动态扩容等任务。

最终还是选择搭建Dledger集群 相对master-slave组有failover能力。相对controller模式部署更简单。

线上RocketMQ Dledger切换

  • 老的单机MQ不要动 新搭建一个Dledger集群 (三台机器) 本来想和ES放在一个机器上 看了下配置 算了 2核3G

  • 配置文件格式代码上线 先用单机

  • 先试CN数据中心 进行切换 业务消息很少 没有数据堆积问题 直接切(容忍个位数的未消费数据丢失)

  • cat /proc/cpuinfo 2核 8g机器 三台

    • broker-n0.conf
    • broker-n1.conf
    • broker-n2.conf
broker-n0.conf
ini 复制代码
brokerClusterName = RaftCluster
brokerName=RaftNode00
namesrvAddr=xxxxxxx:9876
storePathRootDir=/root/rocketmq/rmqstore/node00
storePathCommitLog=/root/rocketmq/rmqstore/node00/commitlog
storePathConsumeQueue=/root/rocketmq/storeDledger/consumequeue
storePathIndex=/root/rocketmq/storeDledger/index
storeCheckpoint=/root/rocketmq/storeDledger/checkpoint
abortFile=/root/rocketmq/storeDledger/abort
enableDLegerCommitLog=true
dLegerGroup=RaftNode00
dLegerPeers=n0-xxx:40911;n1-xxx:40911;n2-xxx:40911
## must be unique
dLegerSelfId=n0
sendMessageThreadPoolNums=4
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerIP1=xxxx
brokerIP2=xxxx

执行启动命令

bash 复制代码
nohup sh bin/mqnamesrv > nohubNameserv &
nohup sh bin/mqbroker  > nohubBroker -c conf/dledger/broker-n0.conf &
broker-n1.conf
ini 复制代码
brokerClusterName = RaftCluster
brokerName=RaftNode00
namesrvAddr=xxx:9876
storePathRootDir=/root/rocketmq/rmqstore/node01
storePathCommitLog=/root/rocketmq/rmqstore/node01/commitlog
storePathConsumeQueue=/root/rocketmq/storeDledger/consumequeue
storePathIndex=/root/rocketmq/storeDledger/index
storeCheckpoint=/root/rocketmq/storeDledger/checkpoint
abortFile=/root/rocketmq/storeDledger/abort
enableDLegerCommitLog=true
dLegerGroup=RaftNode00
dLegerPeers=n0-xxx:40911;n1-xxx:40911;n2-xxx:40911
## must be unique
dLegerSelfId=n1
sendMessageThreadPoolNums=4
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
brokerIP1=xxx
brokerIP2=xxx
bash 复制代码
nohup sh bin/mqnamesrv > nohubNameserv &
nohup sh bin/mqbroker  > nohubBroker -c conf/dledger/broker-n1.conf &
broker-n2.conf
ini 复制代码
brokerClusterName = RaftCluster
brokerName=RaftNode00
namesrvAddr=xxx:9876
storePathRootDir=/root/rocketmq/rmqstore/node02
storePathCommitLog=/root/rocketmq/rmqstore/node02/commitlog
storePathConsumeQueue=/root/rocketmq/storeDledger/consumequeue
storePathIndex=/root/rocketmq/storeDledger/index
storeCheckpoint=/root/rocketmq/storeDledger/checkpoint
abortFile=/root/rocketmq/storeDledger/abort
enableDLegerCommitLog=true
dLegerGroup=RaftNode00
dLegerPeers=n0-xxx;n1-xxx:40911;n2-xxx:40911
## must be unique
dLegerSelfId=n2
sendMessageThreadPoolNums=4
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
brokerIP1=xxx
brokerIP2=xxx
bash 复制代码
nohup sh bin/mqnamesrv > nohubNameserv &
nohup sh bin/mqbroker  > nohubBroker -c conf/dledger/broker-n2.conf &
sh bin/mqshutdown broker

Broker 节点杀掉命令 sh bin/mqshutdown broker

RocketMQ 4.9.3 Deleger 高可用集群模式 CPU 使用率过高

  • rocketmq 版本:4.9.3 集群模式:deleger 1master 2slave

  • 问题现象: 在三台机器都正常的情况下,master所在的机器 会一直有两个broker 线程占用 100% CPU,将master kill 后,重新选举出来的master同样会出现这个问题,kill 2个slave 节点 ,master 上的此问题消失

切换高版本RocketMQ 5.x Dledger解决问题

yaml 复制代码
 wget https://dist.apache.org/repos/dist/release/rocketmq/5.2.0/rocketmq-all-5.2.0-bin-release.zip
 unzip rocketmq-all-5.2.0-bin-release.zip
 sh ./bin/mqnamesrv
 sh bin/mqbroker -n localhost:9876

参考

相关推荐
兰亭序咖啡7 分钟前
学透Spring Boot — 018. 优雅支持多种响应格式
java·spring boot·后端
审计侠14 分钟前
Go语言-初学者日记(八):构建、部署与 Docker 化
开发语言·后端·golang
AskHarries26 分钟前
如何开通google Free Tier长期免费云服务器(1C/1G)
后端
码界筑梦坊29 分钟前
基于Django的二手交易校园购物系统
大数据·后端·python·信息可视化·django
东方珵蕴32 分钟前
Logo语言的区块链
开发语言·后端·golang
烛阴32 分钟前
从零到RESTful API:Express路由设计速成手册
javascript·后端·express
uhakadotcom39 分钟前
Mars与PyODPS DataFrame:功能、区别和使用场景
后端·面试·github
信徒_1 小时前
Spring 怎么解决循环依赖问题?
java·后端·spring
小杨4042 小时前
springboot框架项目实践应用十五(扩展sentinel区分来源)
spring boot·后端·spring cloud
FirstMrRight3 小时前
自动挡线程池OOM最佳实践
java·后端