当前位置: 首页 > 科技观察

消息队列Broker主从架构详细设计方案,本篇将主从架构搞定

时间:2023-03-18 19:34:26 科技观察

今天我们就来学习消息队列设计的底层模块,Broker的架构设计。我们知道如何同步MasterBroker和SlaveBroker的消息。Broker如果支持高可用,应该设计成主从架构。之前的分布式存储也对这个架构讲了很多。大家可以自行查阅历史文章。首先,我们来看第一个问题。为了保证我们的MQ中的数据不丢失并且可用,我们将Broker设计成Master-Slave的模式,即一个MasterBroker对应多个SlaveBroker。这样做的好处是当我们的MasterBroker收到消息后,会把消息同步给Slave,这样即使MasterBroker挂了,Slave上还是有数据的。如上,我们想一下MasterBroker是如何向SlaveBroker同步数据的?一般有两种解决方案:MasterBroker主动推送消息给SlaveBroker。SlaveBroker向MasterBroker发送拉取消息数据的请求。我们采用更可靠的第二种拉取方案,让SlaveBroker不断向MasterBroker发送请求,实现pull方式拉取消息。MQ是否实现了读写分离?从上面我们已经知道MasterBroker主要是用来接收消息然后同步给SlaveBroker的,所以SlaveBroker也有完全一样的数据。既然如此,那么我们接下来的问题是,消费者系统应该从MasterBroker还是SlaveBroker那里获取消息呢?事实上,我们不能简单地获取主从的消息。应该更聪明一些,可以从Master那里得到,也可以从Slave那里得到。作为消费者系统,在获取消息时,首先会向MasterBroker发送请求,然后MasterBroker会返回一批消息给消费者系统。然后,当MasterBroker向消费者系统返回消息时,会根据自身的负载和与Slave的同步情况,向消费者系统建议下次从MasterBroker还是从SlaveBroker获取消息。比如现在Master负载很重,要抗10万写并发,然后你要从它那里获取消息,会给Master带来更重的负担,那么MasterBroker会建议你去SlaveBroker来拉消息。比如现在MasterBroker收到了100万条消息,但是SlaveBroker机器不知道为什么,只同步到96万条消息,落后了4万条消息。这个时候consumer系统可能已经拿到了96条10000条数据,下次就只能从Master那里拉取消息了。因为SlaveBroker同步消息太慢,我们无法从那里获取最新消息。因此,这一切都将由MasterBroker根据实际的负载情况来决定去哪里获取消息。如图:在写消息的时候,一般需要选择MasterBroker来写。消费消息时,可以从MasterBroker上拉取,也可以从SlaveBroker上拉取,视当时情况而定。SlaveBroker宕机有什么影响?现在我们来看下一个问题,如果SlaveBroker挂了,对我们整个系统会有什么影响呢?影响是有一点,但不会太大,所以没什么好怕的。因为消息写的时候都是发给MasterBroker的,然后也可以用MasterBroker来拉取消息,但是有些消息可能会从SlaveBroker拉取。因此,如果SlaveBroker挂掉了,我们可以通过MasterBroker进行消息的写入和获取,不会对我们整个系统造成太大的影响。可能会导致MasterBroker的读写压力增大。MasterBroker挂了怎么办?上面我们分析过,SlaveBroker挂了,不影响整个系统。现在假设我们的MasterBrokker挂了,挂了。会发生什么?这时候,对于写入和获取消息有一定的影响,但本质上,SlaveBroker上有一份数据,只是有些数据还没有从MasterBroker同步过来。一般我们要设计SlaveBroker自动接管MasterBroker的机制。解决方案有两种:人工运维,通过人工切换和借助工具自动切换。手动切换是RocketMQ4.5之前的手动运维方式。当MasterBroker挂掉后,手动修改配置。对SlaveBroker进行相关修改,然后重启机器调整为MasterBroker。期间有点麻烦,会造成短时间不可用。使用上述方式并不能完全实现高可用,因为没有办法自动将SlaveBroker升级为MasterBroker。RocketMQ4.5基于Dledger实现MQ自动切换后,引入了一种新的机制,即Dledger。Dledger是基于Raft协议的一种机制,其底层原理将在后面详细解释。我们先来看看如何基于Dledger实现自动切换。RocketMQ引入Dledger后,一个MasterBroker可以对应多个SlaveBroker,也就是说一份数据会有多份。比如我们有一个MasterBroker对应两个SlaveBroker。这时候如果有一个MasterBroker挂了,还会有多个Slave,然后通过Dledger技术和Raft协议选出leader。其实选高手算法我有专门的文章,大家可以看看(就是面试我经常被问分布式系统核心的,这次没人难倒你)。这样就会选出一个新的Masterbroker对外提供服务。这样整个过程会非常快,大约十几秒或者几十秒就可以完成切换动作,并且完全自动选择SlaveBroker作为Masterbroker对外提供服务,从而达到高-可用性模式。

猜你喜欢