本文RocketMQ系列第四篇,主要介绍RocketMQ集群及如何部署自动容灾切换的 RocketMQ-on-DLedger Group。
RocketMQ集群搭建
ROcketMQ集群搭建有以下几种方案:
- 「单Master模式」
- 「多Master模式」
- 「多Master多Slave模式-异步复制」
- 「多Master多Slave模式-同步双写」
其中,
「单Master模式」风险较大,「一旦Broker重启或者宕机时,会导致整个服务不可用」。不建议线上环境使用,可以用于本地测试。
「多Master模式」,一个集群无Slave,全是Master,单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,「消息实时性会受到影响」。
「多Master-Slave异步复制模式」,即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,同时「Master宕机后,消费者仍然可以从Slave消费」,而且此过程对应用透明,不需要人工干预,性能同多Master模式几乎一样。Master宕机会丢失少量的信息。
「多Master-Slave同步双写模式」,数据与服务都无单点故障,Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高,「性能比异步复制模式略低」(大约低10%左右),发送单个消息的RT会略高,且目前版本在主节点宕机后,备机不能自动切换为主机。
我们采用多Master多Slave的异步复制模式来搭建RocketMQ集群。
双主双从集群搭建
1. 在一台虚拟机上安装RocketMQ
在RocketMQ入坑系列第一篇中,已经有安装方法了,很简单,这里不再赘述。
【RocketMQ系列】RocketMQ中的角色详解及实操基本使用
2. 设置配置文件
先在一台虚拟机上操作,设置好配置文件,然后在根据该虚拟机克隆出几台主机出来。
「进入配置文件目录」:
cd /usr/local/rocketmq/conf && ll
可以看到
「搭建两主两从异步复制broker集群,进入2m-2s-async
目录」:
修改「第一组broker的主节点」配置文件broker-a.properties
:
brokerClusterName=RocketMQCluster
brokerName=broker-a
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
namesrvAddr=192.168.2.170:9876;192.168.2.171:9876;192.168.2.172:9876;192.168.2.173:9876
修改「第一组broker的从节点」配置文件broker-a-s.properties
:
brokerClusterName=RocketMQCluster
brokerName=broker-a
brokerId=1
deleteWhen=04
fileReservedTime=48
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
namesrvAddr=192.168.2.170:9876;192.168.2.171:9876;192.168.2.172:9876;192.168.2.173:9876
第二组broker的主从配置文件如法炮制即可。
3. 关键配置项
「namesrvAddr」:nameserver的IP地址,多个IP地址用分号隔开。
「brokerClusterName」:broker集群的名称,这个是整个broker集群的名称,而不是每个主从broker组的名称。同一个集群中,brokerClusterName需一致。
「brokerName」:这个是每个主从broker组的名称,一个master可以有多个slave,但是一个slave只能对应一个master,并且同一master-slave组中他们的brokerName相同。
「brokerId」:同一master-slave组中用brokerId来区分主从,brokerId=0是主节点master,大于1的是从节点。
「deleteWhen」:过期文件真正删除时间。
「fileReservedTime」:Commitlog、ConsumeQueue文件,如果非当前写文件在一定时间间隔内没有再次被更新,则认为是过期文件,可以被删除,RocketMQ不会管这个这个文件上的消息是否被全部消费。
「brokerRole」:Broker的角色。
「flushDiskType」:刷盘方式。
4. 克隆其他三台虚拟机
修改完成后,关闭虚拟机,在克隆出3台虚拟机出来,并修改IP地址和主机名称。
最终RocketMQ集群主机:
5. 启动集群
5.1 启动nameserver
在四台虚拟机上均执行:
### 首先启动Name Server,进入$ROCKETMQ_HOME/bin目录后执行
$ nohup sh mqnamesrv &
### 验证Name Server 是否启动成功
$ tail -f ~/logs/rocketmqlogs/namesrv.log
The Name Server boot success...
为方便(其实是渣电脑不允许开那么多虚拟机。。。),nameserver就在四台主机上启动了,从刚才的配置文件也能看得出:
namesrvAddr=192.168.2.170:9876;192.168.2.171:9876;192.168.2.172:9876;192.168.2.173:9876
NameServer实例时间互不通信,这本身也是RocketMQ的设计亮点之一,即允许不同NameServer之间数据不同步。
5.2 启动broker
在「192.168.2.170」,启动「broker-a」的Master(在RocketMQ安装目录的bin目录下操作)
nohup sh mqbroker -c $ROCKETMQ_HOME/conf/2m-2s-async/broker-a.properties &
在「192.168.2.171」,启动「broker-b」的Master
nohup sh mqbroker -c $ROCKETMQ_HOME/conf/2m-2s-async/broker-b.properties &
在「192.168.2.172」,启动「broker-a」的Slave
nohup sh mqbroker -c $ROCKETMQ_HOME/conf/2m-2s-async/broker-a-s.properties &
在「192.168.2.173」,启动「broker-b」的Slave
nohup sh mqbroker -c $ROCKETMQ_HOME/conf/2m-2s-async/broker-b-s.properties &
这样集群就启动成功了。
RocketMQ-Console
为了能够方便的查看RocketMQ的集群状态,我们安装一下RocketMQ-Console。
在之前的文章中已经介绍并使用过Docker安装RocketMQ-Console,但是有小伙伴反应自己Docker安装的总是出现问题,这里再提供一下非Docker安装方式:
安装完了后,执行如下命令(比如在192.168.2.170):
java -jar rocketmq-console-ng-2.0.0.jar --rocketmq.config.namesrvAddr="192.168.2.170:9876;192.168.2.171:9876;192.168.2.172:9876;192.168.2.173:9876"
然后访问:http://192.168.2.170:8080
:
首页默认显示了nameserver地址。
Cluster信息:
由此证明我们的集群搭建成功了。
集群Master宕机无法进行故障转移
2主2从集群搭建好了,但是这种集群没有容灾能力,也就是说假如一台master挂了,没有办法选举一个新的master出来。
把「broker-b」的master(「192.168.2.171」)服务停掉看一下:
「broker-b」的slave节点并不能主动切换成master。
Dledger新集群
能自动容灾的集群才是好集群
在 RocketMQ 4.5 版本之前,RocketMQ 只有 Master/Slave 一种部署方式,一组 broker 中有一个 Master ,有零到多个 Slave,Slave 通过同步复制或异步复制的方式去同步 Master 数据。
这种部署模式,提供了一定的高可用性。但这样的部署模式,有一定的缺陷。比如故障转移方面,如果主节点挂了,还需要人为手动进行重启或者切换,无法自动将一个从节点转换为主节点。
新的多副本架构首先需要解决自动故障转移的问题,本质上来说是「自动选主」的问题。
这个问题的解决方案基本可以分为两种:
- 利用第三方协调服务集群完成选主,比如 zookeeper 或者 etcd(raft)。这种方案会引入重量级外部组件,加重部署、运维和故障诊断成本,比如在维护 RocketMQ 集群还需要维护 zookeeper 集群,并且 zookeeper 集群故障会影响到 RocketMQ 集群。
- 利用 raft 协议来完成一个自动选主,raft 协议相比前者的优点是不需要引入外部组件,自动选主逻辑集成到各个节点的进程中,节点之间通过通信就可以完成选主。
RocketMQ选择用 「raft」 协议来解决这个问题,而 「DLedger 就是一个基于 raft 协议的 commitlog 存储库」,也是 RocketMQ 实现新的高可用多副本架构的关键。
Dledger集群搭建
RocketMQ-on-DLedger Group
是指一组「相同名称的 Broker」,至少需要 3 个节点,通过 「Raft」 自动选举出一个 Leader,其余节点作为 Follower,并在 Leader 和 Follower 之间复制数据以保证高可用。
RocketMQ-on-DLedger Group
能自动容灾切换,并保证数据一致。
RocketMQ-on-DLedger Group
是可以水平扩展的,也即可以部署任意多个 RocketMQ-on-DLedger Group
同时对外提供服务。
1. 配置 RocketMQ-on-DLedger Group
上面说到,每组RocketMQ-on-DLedger
需要至少3台机器,现在我们在原来的基础上还需要添加2台机器,每组添加一台。
进入dledger配置文件目录下看一眼:
cd /usr/local/rocketmq/conf/dledger && ll
「broker-a
的n0
节点配置」
brokerClusterName = RaftCluster
brokerName=broker-a
listenPort=30911
namesrvAddr=192.168.2.170:9876;192.168.2.171:9876;192.168.2.172:9876;192.168.2.173:9876;192.168.2.174:9876;192.168.2.175:9876
storePathRootDir=/tmp/rmqstore/broker-b
storePathCommitLog=/tmp/rmqstore/broker-b/commitlog
enableDLegerCommitLog=true
dLegerGroup=broker-b
dLegerPeers=n0-192.168.2.170:40911;n1-192.168.2.172:40911;n2-192.168.2.174:40911
## must be unique
dLegerSelfId=n0
sendMessageThreadPoolNums=4
broker-a的n1、n2节点配置类似,注意修改dLegerSelfId
配置项。
「broker-b
的n0
节点配置」
brokerClusterName = RaftCluster
brokerName=broker-b
listenPort=30911
namesrvAddr=192.168.2.170:9876;192.168.2.171:9876;192.168.2.172:9876;192.168.2.173:9876;192.168.2.174:9876;192.168.2.175:9876
storePathRootDir=/tmp/rmqstore/broker-b
storePathCommitLog=/tmp/rmqstore/broker-b/commitlog
enableDLegerCommitLog=true
dLegerGroup=broker-b
dLegerPeers=n0-192.168.2.171:40911;n1-192.168.2.173:40911;n2-192.168.2.175:40911
## must be unique
dLegerSelfId=n0
sendMessageThreadPoolNums=4
全部配置好以后:
4. 启动集群
4.1 启动nameserver
可以多起几个nameserver,这里我把6台主机的nameserver都起了。
4.2 启动broker
启动命令:
nohup sh mqbroker -c $ROCKETMQ_HOME/conf/dledger/broker-a-n0.conf
注意配置文件与主机的对应。
4.3 启动控制台查看
java -jar rocketmq-console-ng-2.0.0.jar --rocketmq.config.namesrvAddr="192.168.2.170:9876;192.168.2.171:9876;192.168.2.172:9876;192.168.2.173:9876;192.168.2.174:9876;192.168.2.175:9876"
4.4 关闭broker-a的master实例 模拟master宕机
4.5 控制台查看集群
可以看到,新集群自动选举出了一个新的Master。
4.6 重启原来宕机的实例
nohup sh mqbroker -c $ROCKETMQ_HOME/conf/dledger/broker-a-n0.conf &
4.7 查看新实例角色
原来的master宕机重启后已经变成了slave。
本次导航结束,以上。
首发公众号 「行百里er」 ,欢迎老铁们关注阅读指正。代码仓库 「GitHub」github.com/xblzer/JavaJourney