4.RocketMQ集群搭建(你懂RocketMQ吗?)

291 阅读11分钟

第一章为简介,第二章特性,第三章纯干货show you the code,第四章为集群搭建。如果文章对您有帮助,请点赞文章,谢谢~

为什么选择集群

集群(Cluster):同一个业务,部署在多台服务器上,这个就叫做集群。

一台服务器满了才将请求转移到另一台服务器,这样会让第一台总是承担最大压力,会导致业务处理速度效率很低,因此我们单独需要一台服务器进行负载均衡,也就是把请求均匀的分摊到不同的服务器中,减轻服务器压力,提高服务器的处理速度,而且这样做以后,哪怕一台服务器挂了,负载均衡服务器就会将请求转发到别的服务器来接受请求,不会使得整个系统瘫痪。

rocketMQ提供的集群模式

  • 单Master模式:
这种方式风险较大,一旦Broker重启或者宕机时,会导致整个服务不可用。不建议线上环境使用,可以用于本地测试。
  • 多Master模式(2M):

    一个集群无Slave,全是Master,例如2个Master或者3个Master,这种模式的优缺点如下:

    • 优点:配置简单,单个Master宕机或重启维护对应用无影响,在磁盘配置为RAID10时,即使机器宕机不可恢复情况下,由于RAID10磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢),性能最高;
    • 缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到影响
  • 多Master多Slave模式-异步复制(2M-2S-Async)

    每个Master配置一个Slave,有多对Master-Slave,HA采用异步复制方式,主备有短暂消息延迟 (毫秒级),这种模式的优缺点如下:

    • 优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,同时Master宕机后,消费者仍然可以从Slave消费,而且此过程对应用透明,不需要人工干预,性能同多Master模式几乎一样;
    • 缺点:Master宕机,磁盘损坏情况下会丢失少量消息。
  • 多Master多Slave模式-同步双写(2M-2S-Sync)

    每个Master配置一个Slave,有多对Master-Slave,HA采用同步双写方式,即只有主备都写成功,才向应用返回成功,这种模式的优缺点如下:

    • 优点:数据与服务都无单点故障,Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高;
  • 缺点:性能比异步复制模式略低(大约低10%左右),发送单个消息的RT会略高,且目前版本在主节点宕机后,备机不能自动切换为主机。

综上所述:选择了异步复制的模式,毕竟如果磁盘不损坏,基本不会丢失消息,是一种相当可靠的模式

Cluster Build 吐血攻略

集群架构图(复制论坛,自己暂时还没有画)

搭建环境:

  • 64 位操作系统,Linux *4台
  • 64位JDK 1.8+
  • Maven 3.2.x
  • git(可选)

开始搭建

通过git/官网下载rocketMQ的zip包

  • git下载命令:git clone https://github.com/apache/rocketmq.git
  • rocketMQ官网下载,下载后输入unzip指令解压zip包即可

Maven打包构建:mvn -Prelease-all -DskipTests clean install -U

待打包完毕后输入如下指令:cd distribution/target/rocketmq-4.7.0/rocketmq-4.7.0 ,这里即为rocketMQ实际的位置

Linux配置环境变量:

vim /etc/profile 
#添加rocketmqhome到环境变量文件中
export ROCKETMQ_HOME=/opt/rocketMQ/rocketmq-all-4.7.0-source-release/distribution/target/rocketmq-4.7.0/rocketmq-4.7.0
#退出编辑后输入如下指令让环境变量生效
source /etc/profile

broker config配置

rocketMQ为我们提供了傻瓜式拆箱即用的集群搭建

[root@rocketMQ rocketmq-4.7.0]# ls
benchmark  bin  conf  lib  LICENSE  nohup.out  NOTICE  README.md
[root@rocketMQ rocketmq-4.7.0]# cd conf
[root@rocketMQ conf]# ls
2m-2s-async  2m-2s-sync  2m-noslave  broker.conf  dledger  logback_broker.xml  logback_namesrv.xml  logback_tools.xml  plain_acl.yml  tools.yml

我们要搭建的是2m-2s-async模式,所以进入这个目录,对里面的broker config文件分别进行配置即可

[root@rocketMQ conf]# cd 2m-2s-async/
[root@rocketMQ 2m-2s-async]# ls
broker-a.properties  broker-a-s.properties  broker-b.properties  broker-b-s.properties
  • 配置broker-a.properties(Master)

    #broker所属哪个集群
    brokerClusterName=LookDoorTest
    #broker 实列名称,主从关系的需要保持名称一致
    brokerName=broker-a
    #brokerId,必须是大等于0的整数,0表示Master,>0表示Slave
    brokerId=0
    #删除文件的时间点,默认为凌晨4点
    deleteWhen=04
    #文件保留时间,默认为48小时
    fileReservedTime=48
    #-ASYNC_MASTER 异步复制Master
    #-SYNC_MASTER  同步双写Master
    #-SLAVE
    brokerRole=ASYNC_MASTER
    #刷盘方式
    #-ASYNC_FLUSH 异步刷盘
    #-SYNC_FLUSH 同步刷盘
    flushDiskType=ASYNC_FLUSH
    #NameSrv集群地址
    namesrvAddr=192.168.41.40:9876;192.168.41.41:9876
    #是否允许broker自动创建Topic,建议线下开启,线上关闭,默认【true】
    autoCreateTopicEnable=true#是否允许broker自动创建订阅组,建议线下开启,线上关闭,默认【true】
    autoCreateSubscriptionGroup=true
    #开启SQL92过滤
    enablePropertyFilter=true
    #开启消息轨迹
    traceTopicEnable=true
    #broker公网ip
    brokerIP1=192.168.41.40
    
  • 配置broker-a-s.properties(Slave)

    #broker所属哪个集群
    brokerClusterName=LookDoorTest
    #broker 实列名称,主从关系的需要保持名称一致
    brokerName=broker-a
    #brokerId,必须是大等于0的整数,0表示Master,>0表示Slave
    brokerId=1
    #删除文件的时间点,默认为凌晨4点
    deleteWhen=04
    #文件保留时间,默认为48小时
    fileReservedTime=48
    #-ASYNC_MASTER 异步复制Master
    #-SYNC_MASTER  同步双写Master
    #-SLAVE
    brokerRole=SLAVE
    #刷盘方式
    #-ASYNC_FLUSH 异步刷盘
    #-SYNC_FLUSH 同步刷盘
    flushDiskType=ASYNC_FLUSH
    #NameSrv集群地址
    namesrvAddr=192.168.41.40:9876;192.168.41.41:9876
    #是否允许broker自动创建Topic,建议线下开启,线上关闭,默认【true】
    autoCreateTopicEnable=true#是否允许broker自动创建订阅组,建议线下开启,线上关闭,默认【true】
    autoCreateSubscriptionGroup=true
    #开启SQL92过滤
    enablePropertyFilter=true
    #开启消息轨迹
    traceTopicEnable=true
    #公网Ip
    brokerIP1=192.168.41.42
    
  • 配置broker-b.properties(Master)

    #broker所属哪个集群
    brokerClusterName=LookDoorTest
    #broker 实列名称,主从关系的需要保持名称一致
    brokerName=broker-b
    #brokerId,必须是大等于0的整数,0表示Master,>0表示Slave
    brokerId=0
    #删除文件的时间点,默认为凌晨4点
    deleteWhen=04
    #文件保留时间,默认为48小时
    fileReservedTime=48
    #-ASYNC_MASTER 异步复制Master
    #-SYNC_MASTER  同步双写Master
    #-SLAVE
    brokerRole=ASYNC_MASTER
    #刷盘方式
    #-ASYNC_FLUSH 异步刷盘
    #-SYNC_FLUSH 同步刷盘
    flushDiskType=ASYNC_FLUSH
    #NameSrv集群地址
    namesrvAddr=192.168.41.40:9876;192.168.41.41:9876
    #是否允许broker自动创建Topic,建议线下开启,线上关闭,默认【true】
    autoCreateTopicEnable=true#是否允许broker自动创建订阅组,建议线下开启,线上关闭,默认【true】
    autoCreateSubscriptionGroup=true
    #开启SQL92过滤
    enablePropertyFilter=true
    #开启消息轨迹
    traceTopicEnable=true
    #公网Ip
    brokerIP1=192.168.41.41
    
  • 配置broker-b-s.properties(Slave)

    #broker所属哪个集群
    brokerClusterName=LookDoorTest
    #broker 实列名称,主从关系的需要保持名称一致
    brokerName=broker-b
    #brokerId,必须是大等于0的整数,0表示Master,>0表示Slave
    brokerId=1
    #删除文件的时间点,默认为凌晨4点
    deleteWhen=04
    #文件保留时间,默认为48小时
    fileReservedTime=48
    #-ASYNC_MASTER 异步复制Master
    #-SYNC_MASTER  同步双写Master
    #-SLAVE
    brokerRole=SLAVE
    #刷盘方式
    #-ASYNC_FLUSH 异步刷盘
    #-SYNC_FLUSH 同步刷盘
    flushDiskType=ASYNC_FLUSH
    #NameSrv集群地址
    namesrvAddr=192.168.41.40:9876;192.168.41.41:9876
    #是否允许broker自动创建Topic,建议线下开启,线上关闭,默认【true】
    autoCreateTopicEnable=true#是否允许broker自动创建订阅组,建议线下开启,线上关闭,默认【true】
    autoCreateSubscriptionGroup=true
    #开启SQL92过滤
    enablePropertyFilter=true
    #开启消息轨迹
    traceTopicEnable=true
    #公网Ip
    brokerIP1=192.168.41.43
    

开始前最后的准备工作

因为我们需要在4台linux机器上部署集群,所有我们可以通过指令将我们配置好的2m-2s-async下的properties发送给其余3台机器

scp -r ../conf/2m-2s-async root@192.168.41.41:/opt/rocketMQ/rocketmq-all-4.7.0-source-release/distribution/target/rocketmq-4.7.0/rocketmq-4.7.0/conf/
scp -r ../conf/2m-2s-async root@192.168.41.42:/opt/rocketMQ/rocketmq-all-4.7.0-source-release/distribution/target/rocketmq-4.7.0/rocketmq-4.7.0/conf/
scp -r ../conf/2m-2s-async root@192.168.41.43:/opt/rocketMQ/rocketmq-all-4.7.0-source-release/distribution/target/rocketmq-4.7.0/rocketmq-4.7.0/conf/

在集群启动前要确保防火墙关闭

systemctl stop firewalld

Start

启动两台Namesrv

4台机器请分别进入当前目录(bin):/opt/rocketMQ/rocketmq-all-4.7.0-source-release/distribution/target/rocketmq-4.7.0/rocketmq-4.7.0/bin

其中40,41机器输入如下指令:

nohup sh mqnamesrv &

可以查看日志,查看是否启动成功

 tail -fn 300  ~/logs/rocketmqlogs/namesrv.log
 The Name Server boot success...

之后40,41,42,43 这四台机器分别输入如下指令启动broker

#40
nohup sh mqbroker -c $ROCKETMQ_HOME/conf/2m-2s-async/broker-a.properties &
#41
nohup sh mqbroker -c $ROCKETMQ_HOME/conf/2m-2s-async/broker-b.properties &
#42
nohup sh mqbroker -c $ROCKETMQ_HOME/conf/2m-2s-async/broker-a-s.properties &
#43
nohup sh mqbroker -c $ROCKETMQ_HOME/conf/2m-2s-async/broker-b-s.properties &
​

验证集群是否启动成功

[root@rocketMQ bin]# sh mqadmin clusterList  -n 192.168.41.40:9876
RocketMQLog:WARN No appenders could be found for logger (io.netty.util.internal.PlatformDependent0).
RocketMQLog:WARN Please initialize the logger system properly.
#Cluster Name     #Broker Name            #BID  #Addr                  #Version                #InTPS(LOAD)       #OutTPS(LOAD) #PCWait(ms) #Hour #SPACE
LookDoorTest      broker-a                0     192.168.41.40:10911    V4_7_0                   0.00(0,0ms)         0.00(0,0ms)          0 440671.36 0.0424
LookDoorTest      broker-a                1     192.168.41.42:10911    V4_7_0                   0.00(0,0ms)         0.00(0,0ms)          0 440671.36 0.0424
LookDoorTest      broker-b                0     192.168.41.41:10911    V4_7_0                   0.00(0,0ms)         0.00(0,0ms)          0 440671.36 0.0422
LookDoorTest      broker-b                1     192.168.41.43:10911    V4_7_0                   0.00(0,0ms)         0.00(0,0ms)          0 440671.36 0.0417

当我们可以看到如上所示的画面时,说明大功告成

至此rocketMQ集群搭建完毕

集群升级为容灾集群(多副本集群_Dledger Cluster)

为什么要容灾集群?

通过之前讲解的集群模式,我们可以看到2m-2s-async已经是一种高可用的集群模式了。但是在实际的生产中,如果master节点真的挂了,那其实仍然是需要研发人员立即去维护的,毕竟slave只能对消息做读操作,也就是可以让已经在broker的消息被consumer消费,而无法做写操作,producer继续发送消息。

这时候大家必然会想到Kafka的强绑定组件Zookeeper,Zookeeper支持2n+1的部署机制,当leader挂了之后follower会立即选举一台新的leader出来。既然Kafka可以通过zookeeper实现,rocketMQ自然也可以,不过并不是通过多维护一套重组件(Zookeeper)而是使用了RAFT协议.

容灾集群的搭建

容灾集群与zookeeper一样,支持选举与数据同步。容灾集群的搭建也是保持着开箱即用的特点:

在rocketmq的conf目录中我们可以看到目录:dledger

[root@rocketMQ rocketmq-4.7.0]# ls
benchmark  bin  conf  lib  LICENSE  nohup.out  NOTICE  README.md
[root@rocketMQ rocketmq-4.7.0]# cd conf
[root@rocketMQ conf]# ls
2m-2s-async  2m-2s-sync  2m-noslave  broker.conf  dledger  logback_broker.xml  logback_namesrv.xml  logback_tools.xml  plain_acl.yml  tools.yml

dledger目录就是容灾集群的开箱配置目录

Dledger是一个基于Raft的 Commitlog 存储 Library。DLedger 定位是一个工业级的 Java Library,可以友好地嵌入各类 Java 系统中,满足其高可用、高可靠、强一致的需求。Dledger是基于日志实现的,只拥有日志的写入和读出接口,且对顺序读出和随机读出做了优化。 DLedger 的实现大体可以分为以下两个部分: 1.选举 Leader 2.复制日志

依次配置其中的

broker-n0.conf

#broker所属哪个集群
brokerClusterName=LookDoorTest
##broker 实列名称,主从关系的需要保持名称一致
brokerName=lookdoor-broker
#brokerId,必须是大等于0的整数,0表示Master,>0表示Slave
brokerId = 0
#删除文件的时间点,默认为凌晨4点
deleteWhen=04
##文件保留时间,默认为48小时
fileReservedTime=48
##刷盘方式
##-ASYNC_FLUSH 异步刷盘
##-SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
#NameSrv集群地址
namesrvAddr=192.168.41.41:9876;192.168.41.42:9876
##是否允许broker自动创建Topic,建议线下开启,线上关闭,默认【true】
autoCreateTopicEnable=true
##是否允许broker自动创建订阅组,建议线下开启,线上关闭,默认【true】
autoCreateSubscriptionGroup=true
##开启SQL92过滤
enablePropertyFilter=true
##开启消息轨迹
traceTopicEnable=true
brokerIP1=192.168.41.41
brokerIP2=192.168.41.41
#dledger配置
storePathRootDir=/tmp/rmqstore/node00
storePathCommitLog=/tmp/rmqstore/node00/commitlog
enableDLegerCommitLog=true
dLegerGroup=lookdoor-broker
dLegerPeers=n0-192.168.41.41:40911;n1-192.168.41.42:40911;n2-192.168.41.43:40911
## must be unique
dLegerSelfId=n0
sendMessageThreadPoolNums=16

broker-n1.conf

#broker所属哪个集群
brokerClusterName=LookDoorTest
###broker 实列名称,主从关系的需要保持名称一致
brokerName=lookdoor-broker
##brokerId,必须是大等于0的整数,0表示Master,>0表示Slave
brokerId = 1
##删除文件的时间点,默认为凌晨4点
deleteWhen=04
###文件保留时间,默认为48小时
fileReservedTime=48
##-ASYNC_MASTER 异步复制Master
###-SYNC_MASTER  同步双写Master
###-SLAVE
brokerRole=SLAVE
###刷盘方式
###-ASYNC_FLUSH 异步刷盘
###-SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
##NameSrv集群地址
namesrvAddr=192.168.41.41:9876;192.168.41.42:9876
###是否允许broker自动创建Topic,建议线下开启,线上关闭,默认【true】
autoCreateTopicEnable=true
###是否允许broker自动创建订阅组,建议线下开启,线上关闭,默认【true】
autoCreateSubscriptionGroup=true
###开启SQL92过滤
enablePropertyFilter=true
###开启消息轨迹
traceTopicEnable=true
brokerIP1=192.168.41.42
brokerIP2=192.168.41.42
##dledger配置
storePathRootDir=/tmp/rmqstore/node01
storePathCommitLog=/tmp/rmqstore/node01/commitlog
enableDLegerCommitLog=true
dLegerGroup=lookdoor-broker
dLegerPeers=n0-192.168.41.41:40911;n1-192.168.41.42:40911;n2-192.168.41.43:40911
### must be unique
dLegerSelfId=n1
sendMessageThreadPoolNums=16

broker-n2.conf

#broker所属哪个集群
brokerClusterName=LookDoorTest
###broker 实列名称,主从关系的需要保持名称一致
brokerName=lookdoor-broker
##brokerId,必须是大等于0的整数,0表示Master,>0表示Slave
brokerId = 2
##删除文件的时间点,默认为凌晨4点
deleteWhen=04
###文件保留时间,默认为48小时
fileReservedTime=48
###刷盘方式
###-ASYNC_FLUSH 异步刷盘
###-SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
##NameSrv集群地址
namesrvAddr=192.168.41.41:9876;192.168.41.42:9876
###是否允许broker自动创建Topic,建议线下开启,线上关闭,默认【true】
autoCreateTopicEnable=true
###是否允许broker自动创建订阅组,建议线下开启,线上关闭,默认【true】
autoCreateSubscriptionGroup=true
###开启SQL92过滤
enablePropertyFilter=true
###开启消息轨迹
traceTopicEnable=true
brokerIP1=192.168.41.43
brokerIP2=192.168.41.43
##dledger配置
storePathRootDir=/tmp/rmqstore/node02
storePathCommitLog=/tmp/rmqstore/node02/commitlog
enableDLegerCommitLog=true
dLegerGroup=lookdoor-broker
dLegerPeers=n0-192.168.41.41:40911;n1-192.168.41.42:40911;n2-192.168.41.43:40911
### must be unique
dLegerSelfId=n2
sendMessageThreadPoolNums=16