文章目录
1:RocketMQ 的 DLedger 介绍
1.1:引子
上篇博客,我们在搭建 rocketmq 的双主双从集群的时候提到了一点,在 RocketMQ 3.5 版本之前,RocketMQ 只有 Master/Slave 一种部署方式,一组 broker 中有一个 Master ,有零到多个 Slave,Slave 通过同步复制或异步复制的方式去同步 Master 数据。Master/Slave 部署模式,提供了一定的高可用性。
缺点:但这样的部署模式,有一定缺陷。比如故障转移方面,如果主节点挂了,还需要人为手动进行重启或者切换,无法自动将一个从节点转换为主节点。
解决方法:本质上来说是自动选主的问题。这个问题的解决方案基本可以分为两种:
a:利用第三方协调服务集群 zookeeper 完成选主,种方案会引入了重量级外部组件,加重部署,
运维和故障诊断成本,比如在维护 RocketMQ 集群还需要维护 zookeeper 集群,并且 zookeeper 集群故障会影响到 RocketMQ 集群。
b:利用 raft 协议来完成一个自动选主,raft 协议相比前者的优点是不需要引入外部组件,自动选主逻辑集成到各个节点的进程中,节点之间通过通信就可以完成选主。
rocketmq 的选择:RocketMQ 借助 DLedger 组件来完成的,实现 raft 协议,但只用了一些核心的机制。
1.2:DLedger 的作用
提供了 数据同步 和 过半选举的功能。
数据同步:在不引入 DLedger 的时候,procuder 给 broker 发送消息,会将消息通过 append 方法写进 CommitLog ,主节点拷贝 CommitLog ,同步给从节点。在引入 DLedger 之后,会将消息通过 append 方法写进 CommitLog ,DLedger 封装 CommitLog 成 DLedgerCommitLog,这个数据处于不可用状态,DLedger 将这DLedgerCommitLog 同步给 其他的从节点,从节点同步完成后给主节点ack,当收到的 ack 超过从节点个数的一半时,会将刚才同步的数据置成可用状态,并且给 Procuder ack.
过半选举:主备之间通过 DLedger 完成心跳来建立联系。当 Master 挂了之后,DLedger 开始选举主节点,因此,要求一个 Broker 集群的服务器不能少于3台,不然无法提供选举。大家都知道过半选举,如果只有两台机器,挂掉了一台,剩下一台自己选自己,显然是不成立的。
1.3:DLedger 的选举的注意点
rocketmq 中可以由多个 broker 集群,我们为了说清楚这个问题,把一个 broker 集群当成一个帮派,broker 中主节点就是 帮派中的内门,broker 中从节点就是帮派的外门,一个内门可以由多个外门。不管是内门还是外门,都有一个 DLedger ,充当的角色就是军师。
假设现在有两个broker 集群,都是一主两从的.
简化模型: 斧头帮有一个内门A,两个外门 A-1,A-2;大刀帮有一个内门 B,两个外门 B-1,B-2.
问题:有一天斧头帮的内门A 完了,需要重新选一个 斧头帮的内门。
解决方法:肯定是斧头帮的两个外门的两个军师 DLedger 来商量谁成为内门,大刀帮不能掺杂别人帮派的事情。
注意点:各个broker 集群之间的 DLedger 是不影响的,以集群为单位 DLedger 隔离。
2:基于DLedger的主备切换集群搭建
2.1:机器准备
还是上次的四台机器,rocketmq-151,rocketmq-152,rocketmq-153,rocketmq-154,
链接:https://blog.csdn.net/qq_40230026/article/details/122930494
这次准备搭建一主三从的,并测试他们的选主功能。
2.2:四台机器启动 NameServer
通过xshell 链接,进入到 rocketmq 文件夹下的 bin 目录下,后台启动 NameServer,可以四台机器分别启动,也可以和上次搭建集群一样,通过 xshell 发送命令同时启动
cd /usr/local/rocketmq-4.7.1/bin
ls
./mqnamesrv &
2.3:配置 rocketmq-151 的配置文件(主)
从 bin 目录进入到配置文件文件夹,并进入到 broker-a 的从配置文件 broker-a.properties
cd ../conf/2m-2s-async/
ls
vi broker-a.properties
添加 DLedger 的配置
# 这个NameserAddr 也是要配置的,我的是上次搭建集群配置了,这此不用写入了
namesrvAddr=192.168.10.151:9876;192.168.10.152:9876;192.168.10.153:9876;192.168.10.154:9876
# dleger 配置
enableDLegerCommitLog = true
dLegerGroup = broker-a
dLegerPeers = n0-192.168.10.151:40911;n1-192.168.10.152:40911;n2-192.168.10.153:40911;n3-192.168.10.154:40911
# 注意:这里是 n0
dLegerSelfId = n0
sendMessageThreadPoolNums = 4
配置完成,开启 broker
cd ../../bin
./mqbroker -c ../conf/2m-2s-async/broker-a.properties
2.4:配置 rocketmq-152 的配置文件(备)
从 bin 目录进入到配置文件文件夹,并进入到 broker-a 的从配置文件 broker-a-s.properties
cd ../conf/2m-2s-async/
ls
vi broker-a-s.properties
添加 DLedger 的配置
# 这个NameserAddr 也是要配置的,我的是上次搭建集群配置了,这此不用写入了
namesrvAddr=192.168.10.151:9876;192.168.10.152:9876;192.168.10.153:9876;192.168.10.154:9876
# dleger 配置,注意ID
enableDLegerCommitLog = true
dLegerGroup = broker-a
dLegerPeers = n0-192.168.10.151:40911;n1-192.168.10.152:40911;n2-192.168.10.153:40911;n3-192.168.10.154:40911
# 注意:这里是 n1
dLegerSelfId = n1
sendMessageThreadPoolNums = 4
配置完成,开启 broker
cd ../../bin
./mqbroker -c ../conf/2m-2s-async/broker-a-s.properties
2.4:配置 rocketmq-153 的配置文件(备)
从 bin 目录进入到配置文件文件夹,并进入到 broker-a 的从配置文件 broker-a-s.properties
cd ../conf/2m-2s-async/
ls
vi broker-a-s.properties
添加 DLedger 的配置,并且修改配置信息,将borkerId=2
# 这个NameserAddr
namesrvAddr=192.168.10.151:9876;192.168.10.152:9876;192.168.10.153:9876;192.168.10.154:9876
# dleger 配置,注意ID
enableDLegerCommitLog = true
dLegerGroup = broker-a
dLegerPeers = n0-192.168.10.151:40911;n1-192.168.10.152:40911;n2-192.168.10.153:40911;n3-192.168.10.154:40911
# 注意:这里是 n2
dLegerSelfId = n2
sendMessageThreadPoolNums = 4
配置完成,开启 broker
cd ../../bin
./mqbroker -c ../conf/2m-2s-async/broker-a-s.properties
2.5:配置 rocketmq-154 的配置文件(备)
从 bin 目录进入到配置文件文件夹,并进入到 broker-a 的从配置文件 broker-a-s.properties
cd ../conf/2m-2s-async/
ls
vi broker-a-s.properties
添加 DLedger 的配置,并且修改配置信息,将borkerId=3
# 这个NameserAddr
namesrvAddr=192.168.10.151:9876;192.168.10.152:9876;192.168.10.153:9876;192.168.10.154:9876
# dleger 配置,注意ID
enableDLegerCommitLog = true
dLegerGroup = broker-a
dLegerPeers = n0-192.168.10.151:40911;n1-192.168.10.152:40911;n2-192.168.10.153:40911;n3-192.168.10.154:40911
# 注意:这里是 n3
dLegerSelfId = n3
sendMessageThreadPoolNums = 4
配置完成,开启 broker
cd ../../bin
./mqbroker -c ../conf/2m-2s-async/broker-a-s.properties
3:启动控制台,查看集群情况
我们通过 xshell 随便连接 四台机器中的一个,我这边连接 rocketmq-151,java-jar 启动控制台的springboot 项目,并通过浏览器去访问
// 这里也可以随意制定nameServer中的一个,我这里不指定,到控制台去输入
java -jar rocketmq-console-ng-1.0.1.jar
能看到,启动成功,端口是 8080,我们到浏览器去访问
点击 OPS,输入一个nameServer,查看集群情况,注意nameServer 的端口号是 9876,也要输入
我们点击 Cluster ,查看集群情况
可以看到一主三从的集群。
4:测试选主
有上图可以看到, IP 地址 151 的是主节点,其余三个是从节点。我们手动断开 151,观察 选主情况
刷新浏览器
可以看到 154 变成了主节点,我们再次手动断开 154,观察剩下的选主情况
刷新浏览器
剩下两台,选不出来主了,原因很简单,各自投一票给别人,票数无法超过一半。
这就要求:机器数量最少三台,否则也是无法选主的。