RocketMQ集群搭建
文章目录
数据复制与刷盘策略
数据复制
复制策略是Broker的Master和Slave之间的数据同步方式。分为同步复制和异步复制。
- 同步复制:消息写入master后,master会等待slave同步数据成功后才向producer返回成功ACK
- 异步复制(降低写入延迟,提高吞吐量),消息写入master后,master立即向producer返回成功ACK,无需等待slave同步数据成功。
异步复制: 降低写入延迟,RT变小,提高了吞吐量。
如何才知道数据是否成功了?涉及到刷盘策略
刷盘策略
刷盘策略指的是broker中的消息的落盘方式,即消息发送到broker内存后消息持久化到磁盘的方式。分为同步刷盘和异步刷盘。
- 同步刷盘:当消息持久化到broker的磁盘后才算是消息写入成功。
- 异步刷盘:当消息写入到broker的内存后即表示消息写入成功,无需等待消息持久化到磁盘。
异步刷盘: 降低写入延迟,RT变小,提高了吞吐量。
消息写入到broker的内存,一般是写入到了PageCache缓存。
对于异步刷盘策略,消息会写入到PageCache后立即返回ACK,并不会立即做落盘操作,而是当PageCache达到一定量会自动落盘。
所以,数据复制成功需要看采用哪种刷盘策略,并且落盘成功才算是数据复制成功了。
Broker集群模式
根据broker集群中各个节点关系的不同,broker集群可以分为以下几类:
单master(单机版)
只有一个broker,只能在测试时使用,生产环境下不能使用,因为存在单点问题。
多master
broker集群由多个master构成,不存在slave。同一个topic是各个queue会分布会平均分布在在各个节点上。
- 优点:配置简单,但哥master宕机或重启维护对应用无影响,在磁盘配饰为RAID10时,即使机器宕机不可恢复情况下,由于RAID10磁盘非常可靠,消息也不会丢失(异步刷盘丢失少量消息,同步刷盘一条不丢),性能最高。
- 缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复前不可订阅,消息实时性会受到影响。
以上有点的前提是,这些master都配置了RAID磁盘阵列,如果没有配置一旦出现某master宕机,则会发生大量消息丢失的情况。
多master多slave模式-异步复制
broker集群由多个master构成,每个master又配置了多个slave(在配置了RAID磁盘阵列的情况下,一个master一般配置一个slave即可)。master与slave的关系是主备关系,即master负责处理消息的读写请求,而slave仅负责消息的备份与master宕机后的角色互换。
异步复制即前面所讲的复制策略中的异步复制策略,即消息写入master成功后,master立即向producer返回成功ACK,无需等待slave同步数据成功。
该模式的最大特点之一是,当master宕机后slave能够自动切换为master。不过由于slave从master的同步具有短暂的延迟(毫秒级),所以当master宕机后,这种异步复制会存在少量的丢失。
slave从master同步的延迟越短,其可能丢失的消息就越少。
对于master的RAID磁盘阵列,若使用的也是异步复制策略,同样也存在延迟问题,同样也可能会丢失消息。但RAID阵列的秘诀是微秒级的(因为是硬盘支持的),所以丢失数据会更少。
多master多slave模式-同步双写
该模式是多master多slave模式的同步复制实现。所谓同步双写,指的是消息写入master成功后,master等待slave同步数据成功后才向producer返回成功ACK,即master与slave都要写入成功后才会返回成功ACK,也即双写。
该模式与异步复制相比,优点是消息的安全性更高,不存在消息丢失的情况。但单个消息的RT略高,从而导致性能略低(大约低10%)。
该模式存在一个大问题:对于目前版本,master宕机后,slave不会自动切换到master。
最佳实现
一般会为master配置RAID10磁盘阵列,然后再为其配置一个slave。即利用了RAID10磁盘阵列的高效、安全性,又解决了可能会影响订阅的问题。
- RAID磁盘阵列的效率要高于master-slave集群,因为RAID是硬件支持的。也正因为如此,所以RAID阵列的搭建成本较高。
- 多master+RAID整列,与多master多slave集群的却别是什么?
- 多master+RAID阵列,其仅仅可以保证数据不丢失,即不影响消息写入,但可能会影响到消息的订。但其执行效率要远高于多master多slave集群。
- 多master多slave集群,其不仅可以保证数据不丢失,也不会影响消息写入。其运行效率要低于多master+RAID阵列。
集群搭建实践
集群架构
搭建一个双主双从异步复制的broker集群。
序号 | 主机 | IP | 功能 | broker角色 |
---|---|---|---|---|
1 | rocketmqOS1 | 192.168.59.164 | NameServer+Broker | master1+slave2 |
2 | rocketmqOS1 | 192.168.59.165 | NameServer+Broker | master2+slave1 |
克隆生成rocketmqOS1
修改主机名和IP
修改hostname为rocketmqOS1
$ vim /etc/hostname
修改IP为192.168.59.165
$ vim /etc/sysconfig/network-scripts/ifcfg-ens33
修改rocketmqOS1配置文件
要修改的文件在安装目录下的conf/2m-2s-async文件里
-
修改broker-a.properties
# 指定整个broker集群的名称,或者说是rocketmq集群的名称 brokerClusterName=DefaultCluster # 指定整个master-slave集群的名称。一个rocketmq集群可以包含多个master-slave集群 brokerName=broker-a # master的brokerId为0,非master的为非0 brokerId=0 # 指定删除消息存储过期文件的时间为凌晨4点 deleteWhen=04 # 指定未发生更新的消息存储文件的保留时长为48小时,48小时后过期,将会被删除 fileReservedTime=48 # 指定当前broker为异步复制master brokerRole=ASYNC_MASTER # 指定刷盘策略为异步刷盘 flushDiskType=ASYNC_FLUSH # 指定name server的地址 namesrvAddr=192.168.59.165:9876;192.168.59.166:9876
-
修改broker-b-s.properties
# 指定整个broker集群的名称,或者说是rocketmq集群的名称 brokerClusterName=DefaultCluster # 指定整个master-slave集群的名称。一个rocketmq集群可以包含多个master-slave集群 brokerName=broker-b # master的brokerId为0,大于0表示slave brokerId=1 # 指定删除消息存储过期文件的时间为凌晨4点 deleteWhen=04 # 指定未发生更新的消息存储文件的保留时长为48小时,48小时后过期,将会被删除 fileReservedTime=48 # Broker的角色: SLAVE brokerRole=ASYNC_MASTER # 刷盘策略: 异步刷盘 flushDiskType=ASYNC_FLUSH # 指定name server的地址 namesrvAddr=192.168.59.165:9876;192.168.59.166:9876 # 指定broker对外提供服务的端口,即broker与producer与consumer通信的端口。默认是10911。由于当前主机同时充当master1和slave2,而前面的master1使用的是默认端口。这里需要将两个端口加以区分,以区分出master1和slave2。 listenPort=11911 # 指定消息存储相关的路径。默认路径为~/store目录。由于当前主机同时充当着master1与slave2,master1使用默认路径,这里就需要再指定一个不同路径 storePathRootDir=~/store-s storePathCommitLog=~/store-s/commmitlog storePathConsumeQueue=~/store-s/consumequeue storePathIndex=~/store-s/index storeCheckpoint=~/store-s/checkpoint abortFile=~/store-s/abort
-
除了以上配置外,这些配置文件中还可以设置其他属性
# 指定整个broker集群的名称,或者说是rocketmq集群的名称 brokerClusterName=rocket-MS # 指定整个master-slave集群的名称。一个rocketmq集群可以包含多个master-slave集群 brokerName=broker-b # master的brokerId为0,大于0表示slave brokerId=0 # 指定删除消息存储过期文件的时间为凌晨4点 deleteWhen=04 # 指定未发生更新的消息存储文件的保留时长为48小时,48小时后过期,将会被删除 fileReservedTime=48 # Broker的角色 # 异步复制master: ASYNC_MASTER # 同步双写master: SYNC_MASTER # slave: SLAVE brokerRole=ASYNC_MASTER # 刷盘策略 # 同步刷盘: SYNC_FLUSH # 异步刷盘: ASYNC_FLUSH flushDiskType=ASYNC_FLUSH # 指定name server的地址 namesrvAddr=192.168.59.165:9876;192.168.59.166:9876 # 指定broker对外提供服务的端口,即broker与producer与consumer通信的端口。默认是10911。由于当前主机同时充当master1和slave2,而前面的master1使用的是默认端口。这里需要将两个端口加以区分,以区分出master1和slave2 listenPort=11911 # HA高可用监听端口,即master与slave间通信的端口,默认值为listenPort+1 haListenPort=10912 # 指定消息存储相关的路径。默认路径为~/store目录。由于当前主机同时充当着master1与slave2,master1使用默认路径,这里就需要再指定一个不同路径 storePathRootDir=~/store-s storePathCommitLog=~/store-s/commmitlog storePathConsumeQueue=~/store-s/consumequeue storePathIndex=~/store-s/index storeCheckpoint=~/store-s/checkpoint abortFile=~/store-s/abort # 默认为新建的Topic所创建的队列数 defaultTopicQueueNums=4 # 是否允许broker自动创建topic,建议生产环境中关闭 autoCreateTopicEnable=false # 是否允许broker自动创建订阅组,建议生产环境中关闭 autoCreateSubscriptionGroup=true # 指定commitLog目录中每个文件的大小,默认1G mapedFileSizeCommitLog=1073741824 # 指定ConsumeQueue的每个Topic的每个Queue文件中可以存放的消息数量,默认为30w条 mapedFileSizeConsumeQueue=300000 # 在清除过期文件时,如果该文件被其他线程所占用(引用数大于0,比如读取消息),此时会阻止本次删除任务,同时在第一次试图删除文件时记录当前时间戳,该属性则表示从 第一次拒绝删除后开始计时,该文件最多可以保留的时长,在此时间内若引用数仍不为0,则删除仍会被拒绝,不过时间到期后,文件将会被强制删除 # destroyMapedFileIntervalForcibly=120000 # 指定消息的最大大小 maxMessageSize=65536 # 发消息线程池数量 sendMessageThreadPoolNums=128 # 拉消息线程池数量 pullMessageThreadPoolNums=128 # 强制本机IP,需要根据每台机器进行修改,官方介绍可以为空,系统默认自动识别,但多网卡时IP地址可能读取错误 brokerIP1=192.168.3.165
rocketmqOS1克隆生成rocketmqOS2
步骤同rocketOS1
修改rocketmqOS2配置文件
-
修改broker-b.properties
# 指定整个broker集群的名称,或者说是rocketmq集群的名称 brokerClusterName=DefaultCluster # 指定整个master-slave集群的名称。一个rocketmq集群可以包含多个master-slave集群 brokerName=broker-b # master的brokerId为0,非master的为非0 brokerId=0 # 指定删除消息存储过期文件的时间为凌晨4点 deleteWhen=04 # 指定未发生更新的消息存储文件的保留时长为48小时,48小时后过期,将会被删除 fileReservedTime=48 # 指定当前broker为异步复制master brokerRole=ASYNC_MASTER # 指定刷盘策略为异步刷盘 flushDiskType=ASYNC_FLUSH # 指定name server的地址 namesrvAddr=192.168.59.165:9876;192.168.59.166:9876
-
修改broker-a-s.properties
# 指定整个broker集群的名称,或者说是rocketmq集群的名称 brokerClusterName=DefaultCluster # 指定整个master-slave集群的名称。一个rocketmq集群可以包含多个master-slave集群 brokerName=broker-a # master的brokerId为0,大于0表示slave brokerId=1 # 指定删除消息存储过期文件的时间为凌晨4点 deleteWhen=04 # 指定未发生更新的消息存储文件的保留时长为48小时,48小时后过期,将会被删除 fileReservedTime=48 # Broker的角色: SLAVE brokerRole=ASYNC_MASTER # 刷盘策略: 异步刷盘 flushDiskType=ASYNC_FLUSH # 指定name server的地址 namesrvAddr=192.168.59.165:9876;192.168.59.166:9876 # 指定broker对外提供服务的端口,即broker与producer与consumer通信的端口。默认是10911。由于当前主机同时充当master1和slave2,而前面的master1使用的是默认端口。这里需要将两个端口加以区分,以区分出master1和slave2。 listenPort=11911 # 指定消息存储相关的路径。默认路径为~/store目录。由于当前主机同时充当着master1与slave2,master1使用默认路径,这里就需要再指定一个不同路径 storePathRootDir=~/store-s storePathCommitLog=~/store-s/commmitlog storePathConsumeQueue=~/store-s/consumequeue storePathIndex=~/store-s/index storeCheckpoint=~/store-s/checkpoint abortFile=~/store-s/abort
启动服务器
启动NameServer集群
分别启动rocketmqOS1和rocketmqOS2两个主机中的MameServer。启动命令完全相同。
$ nohup sh bin/mqnamesrv &
$ tail -f ~/logs/rocketmqlogs/namesrv.log
启动两个master
分别启动rocketmqOS1和rocketmqOS2两个主机中的broker master。注意,他们指定要加载的配置文件是不同的。
# rocketmqOS1
$ nohup sh bin/mqbroker -c conf/2m-2s-async/broker-a.properties &
$ tail -f ~/logs/rocketmqlogs/broker.log
# rocketmqOS2
$ nohup sh bin/mqbroker -c conf/2m-2s-async/broker-b.properties &
$ tail -f ~/logs/rocketmqlogs/broker.log
启动两个slave
# rocketmqOS1
$ nohup sh bin/mqbroker -c conf/2m-2s-async/broker-b-s.properties &
$ tail -f ~/logs/rocketmqlogs/broker.log
# rocketmqOS2
$ nohup sh bin/mqbroker -c conf/2m-2s-async/broker-a-s.properties &
$ tail -f ~/logs/rocketmqlogs/broker.log
启动dashboard
- 修改src\main\resources\application.properties文件中namesrvAddr地址
rocketmq.config.namesrvAddr=rocketmqOS1:9876;rocketmqOS2:9876
- 重新打包
> mvn clean package -Dmaven.test.skip=true
3.运行target\rocketmq-dashboard-1.0.0.jar文件,访问localhost:7000
> java -jar rocketmq-dashboard-1.0.0.jar