RocketMQ分布式集群是通过Master和Slave的配合达到高可用性的。
Master和Slave的区别:在Broker的配置文件中,参数brokerId的值为0表明这个Broker是Master,大于0表明这个Broker是Slave,同时brokerRole参数也会说明这个Broker是Master还是Slave。
Master角色的Broker支持读和写,Slave角色的Broker仅支持读,也就是Producer只能和Master角色的Broker连接写入消息;Consumer可以连接 Master角色的Broker,也可以连接Slave角色的Broker来读取消息。
RocketMQ的刷盘是把消息存储到磁盘上的,这样既能保证断电后恢复,又可以让存储的消息量不受内存的限制。RocketMQ为了提高性能,会尽可能地保证磁盘的顺序写。消息在通过Producer写入RocketMQ的时候,有两种写入的磁盘方式,同步刷盘和异步刷盘。
在properties文件中通过参数flushDiskType指定刷盘方式:
# 同步刷盘
flushDiskType=SYNC_FLUSH
# 异步刷盘
flushDiskType=ASYNC_FLUSH
SYNC_FLUSH(同步刷盘):生产者发送的每一条消息都在保存到磁盘成功后才返回告诉生产者成功。这种方式不会存在消息丢失的问题,但是有很大的磁盘IO开销,性能有一定影响。
ASYNC_FLUSH(异步刷盘):生产者发送的每一条消息并不是立即保存到磁盘,而是暂时缓存起来,然后就返回生产者成功,随后再异步的将缓存数据保存到磁盘。
异步刷盘的时机有两种情况:
异步刷盘的方式可能会丢失消息,如果缓存中的数据还未来得及同步到磁盘的时候宕机,这样缓存中的数据就丢失了,但是性能很好,默认是异步刷盘。
集群环境下需要部署多个Broker,Broker分为两种角色:
一个master与多个slave通过指定相同的brokerClusterName被归为一个broker set(broker集)。
通常生产环境中,我们至少需要2个broker set,2个broker集才能保证高可用。
Slave是复制Master的数据。一个Broker组有Master和Slave,消息需要从Master复制到Slave上,有同步和异步两种复制方式。
同步复制和异步复制是通过Broker配置文件里的brokerRole参数进行设置的,这个参数可以被设置成ASYNC_MASTER、 SYNC_MASTER、SLAVE三个值中的一个。
主从同步方式的相关配置:
# 0代表主
brokerId=0
# 大于0都代表从
brokerId=1
# 主从同步复制SYNC_MASTER
brokerRole=SYNC_MASTER
# 主从异步复制ASYNC_MASTER
brokerRole=ASYNC_MASTER
# SLAVE代表从节点
brokerRole=SLAVE
主从同步复制方式(Sync Broker):生产者发送的每一条消息都至少同步复制到一个slave后才返回告诉生产者成功,即“同步双写”。
在同步复制方式下,如果Master出故障,Slave上有全部的备份数据,容易恢复,但是同步复制会增大数据写入延迟,降低系统吞吐量。
主从异步复制方式(Async Broker):生产者发送的每一条消息只要写入master就返回告诉生产者成功,然后再“异步复制”到slave。
在异步复制方式下,系统拥有较低的延迟和较高的吞吐量,但是如果Master出了故障,有些数据因为没有被写入Slave,有可能会丢失。
刷盘方式和同步方式可以两两组合,形成多种集群部署模式,下面列举一些常用的集群部署模式。
也就是只有一个master节点,称不上是集群,一旦这个master节点宕机,那么整个服务就不可用。
多个master节点组成集群,单个master节点宕机或者重启对应用没有影响。
优点:所有模式中性能最高(一个Topic的可以分布在不同的master,进行横向拓展),在多主的架构体系下,无论使用客户端还是管理界面创建主题,一个主题都会创建多份队列在多主中(默认是4个的话,双主就会有8个队列,每台主4个队列,所以双主可以提高性能,一个Topic的分布在不同的master,方便进行横向拓展。
缺点:单个master节点宕机期间,未被消费的消息在节点恢复之前不可用,消息的实时性就受到影响。
从节点(Slave)就是复制主节点的数据,对于生产者完全感知不到,对于消费者正常情况下也感知不到。只有当Master不可用或者繁忙的时候,Consumer会被自动切换到从Slave读。
在多master模式的基础上,每个master节点都有至少一个对应的slave。master节点可读可写,但是slave只能读不能写。
优点:一般情况下都是master消费,在master宕机或超过负载时,消费者可以从slave读取消息,消息的实时性不会受影响,性能几乎和多master一样。
缺点:使用异步复制的同步方式有可能会有消息丢失的问题。(Master宕机后,生产者发送的消息没有消费完,同时到Slave节点的数据也没有同步完)
优点:主从同步复制模式能保证数据不丢失。
缺点:发送单个消息响应时间会略长,性能相比异步复制低10%左右。
对数据要求较高的场景,主从同步复制方式,保存数据热备份,通过异步刷盘方式,保证rocketMQ高吞吐量。
在RocketMQ4.5版本之后推出了Dlegder模式,类似于Zookeeper的集群选举模式。
虽然master-slave方式提供了一定的高可用性,但是如果集群中的master节点挂了,这时需要运维人员手动进行重启或者切换操作,即不能自动在集群的剩余节点中选出一个master,Dledger模式解决了这个问题。
DLedger基于raft协议,故天然支持主从切换,即主节点 (Leader) 发生故障,会重新触发选主,在集群内再选举出新的主节点。
主机规划:
配置文件RocketMQ已经自带了,位于conf/2m-2s-sync
目录下,只需要稍微修改下即可。
如果机器是通过外网IP进行连接,需要在properties中指定自己的外网IP:
brokerIP1=xxx.xxx.xxx.xxx
192.168.100.100(MasterA、NameServerA)的操作如下:
namesrvAddr=192.168.100.100:9876;192.168.100.101:9876
$ nohup sh mqnamesrv &
$ nohup sh mqbroker -c ../conf/2m-2s-sync/broker-a.properties &
192.168.100.101(MasterB、NameServerB)的操作如下:
namesrvAddr=192.168.100.100:9876;192.168.100.101:9876
$ nohup sh mqnamesrv &
$ nohup sh mqbroker -c ../conf/2m-2s-sync/broker-b.properties &
192.168.100.102(SlaveA、dashboard)的操作如下:
namesrvAddr=192.168.100.100:9876;192.168.100.101:9876
$ nohup sh mqbroker -c ../conf/2m-2s-sync/broker-a-s.properties &
$ nohup java -jar rocketmq-dashboard-1.0.1-SNAPSHOT.jar &
192.168.100.103(SlaveB)的操作如下:
namesrvAddr=192.168.100.100:9876;192.168.100.101:9876
$ nohup sh mqbroker -c ../conf/2m-2s-sync/broker-b-s.properties &
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e6V1V3ru-1659147846043)(https://s3.bmp.ovh/imgs/2022/07/30/740dc6f9e87a7139.png)]
管理后台地址:http://192.168.100.102:8080
可以在管理后台里面手动添加namesrv的地址:192.168.100.100:9876、192.168.100.101:9876