行百里er 行百里er
首页
  • 分类
  • 标签
  • 归档
设计模式
  • JVM
  • Java基础
MySQL
Elastic Stack
Redis
  • Kafka
  • RocketMQ
分布式
Spring Cloud Alibaba
云原生
数据结构与算法
关于
GitHub (opens new window)

行百里er

Java程序员一枚
首页
  • 分类
  • 标签
  • 归档
设计模式
  • JVM
  • Java基础
MySQL
Elastic Stack
Redis
  • Kafka
  • RocketMQ
分布式
Spring Cloud Alibaba
云原生
数据结构与算法
关于
GitHub (opens new window)
  • Kafka

  • RocketMQ

    • 【RocketMQ】RocketMQ入门之闪电三连鞭:消息队列、RocketMQ介绍及安装使用
    • 【RocketMQ】近距离感受RocketMQ如何收发消息,有备而来!
    • 【RocketMQ】基于RocketMQ的分布式事务
    • 【RocketMQ】RocketMQ集群,RocketMQ-on-DLedger可容灾集群
      • RocketMQ集群搭建
        • 双主双从集群搭建
        • 1. 在一台虚拟机上安装RocketMQ
        • 2. 设置配置文件
        • 3. 关键配置项
        • 4. 克隆其他三台虚拟机
        • 5. 启动集群
        • 5.1 启动nameserver
        • 5.2 启动broker
      • RocketMQ-Console
      • 集群Master宕机无法进行故障转移
      • Dledger新集群
        • 能自动容灾的集群才是好集群
        • Dledger集群搭建
        • 1. 配置 RocketMQ-on-DLedger Group
        • 4. 启动集群
        • 4.1 启动nameserver
        • 4.2 启动broker
        • 4.3 启动控制台查看
        • 4.4 关闭broker-a的master实例 模拟master宕机
        • 4.5 控制台查看集群
        • 4.6 重启原来宕机的实例
        • 4.7 查看新实例角色
  • 消息中间件
  • RocketMQ
行百里er
2020-11-19
目录

【RocketMQ】RocketMQ集群,RocketMQ-on-DLedger可容灾集群

作者:行百里er

博客:https://chendapeng.cn (opens new window)

提示

这里是 行百里er 的博客:行百里者半九十,凡事善始善终,吾将上下而求索!

本文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中的角色详解及实操基本使用 (opens new window)

# 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
1
2
3
4
5
6
7
8
9

修改第一组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
1
2
3
4
5
6
7
8
9

第二组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...
1
2
3
4
5
6

为方便(其实是渣电脑不允许开那么多虚拟机。。。),nameserver就在四台主机上启动了,从刚才的配置文件也能看得出:

namesrvAddr=192.168.2.170:9876;192.168.2.171:9876;192.168.2.172:9876;192.168.2.173:9876
1

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 &
1

在192.168.2.171,启动broker-b的Master

nohup sh mqbroker -c $ROCKETMQ_HOME/conf/2m-2s-async/broker-b.properties &
1

在192.168.2.172,启动broker-a的Slave

nohup sh mqbroker -c $ROCKETMQ_HOME/conf/2m-2s-async/broker-a-s.properties &
1

在192.168.2.173,启动broker-b的Slave

nohup sh mqbroker -c $ROCKETMQ_HOME/conf/2m-2s-async/broker-b-s.properties &
1

这样集群就启动成功了。

# 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"
1

然后访问: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
1
2
3
4
5
6
7
8
9
10
11
12

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
1
2
3
4
5
6
7
8
9
10
11
12

全部配置好以后:

# 4. 启动集群

# 4.1 启动nameserver

可以多起几个nameserver,这里我把6台主机的nameserver都起了。

# 4.2 启动broker

启动命令:

nohup sh mqbroker -c $ROCKETMQ_HOME/conf/dledger/broker-a-n0.conf
1

注意配置文件与主机的对应。

# 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"
1

# 4.4 关闭broker-a的master实例 模拟master宕机

# 4.5 控制台查看集群

可以看到,新集群自动选举出了一个新的Master。

# 4.6 重启原来宕机的实例
nohup sh mqbroker -c $ROCKETMQ_HOME/conf/dledger/broker-a-n0.conf &
1
# 4.7 查看新实例角色

原来的master宕机重启后已经变成了slave。

本次导航结束,以上。


首发公众号 行百里er ,欢迎老铁们关注阅读指正。

#RocketMQ
上次更新: 2022/10/04, 18:14:30
【RocketMQ】基于RocketMQ的分布式事务

← 【RocketMQ】基于RocketMQ的分布式事务

最近更新
01
重要数据不能丢!MySQL数据库定期备份保驾护航!
05-22
02
分布式事务解决方案之 Seata(二):Seata AT 模式
09-09
03
Seata 番外篇:使用 docker-compose 部署 Seata Server(TC)及 K8S 部署 Seata 高可用
09-05
更多文章>
Theme by Vdoing | Copyright © 2020-2023 行百里er | MIT License | 豫ICP备2022020385号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式