开足码力,码动人生,本文首发公众号【 Craig无忌 】,关注这个一言不合就开车的的代码界老司机
本文 GitHub上已经收录 https://github.com/BeKingCoding/JavaKing , 一线大厂面试核心知识点、我的联系方式和技术交流群,欢迎Star和完善
前言
通过之前的两篇文章,向大家介绍了消息中间件 MQ ,大家可以看:
本篇文章以目前比较流行的 RocketMQ 为例,讲解一下相关的技术,帮助大家更好地理解消息中间件。
正文
首先看第一个问题,我们都知道为了保证高可用,目前基本上所有的组件都会采用主从的架构设计,经典的有 MySQL《MySQL是如何实现主从备份的?》
RocketMQ 为了保证数据的不丢失而且具备一定的高可用性,所以一般都是会把 Broker 部署成 Master-Slave 模式,也就是一个Master Broker对应一个Slave Broker。
Master 在接收到消息之后,将数据同步给Slave,这样一旦Master Broker挂了,Slave上还有一份备份数据。
整个架构的设计还是比较常见的,在这里我们要考虑一个问题:
Master Broker 如何将消息同步给 Slave Broker?
是 Master Broker 主动推送给Slave Broker ?还是 Slave Broker 发送请求到 Master Broker 去拉取?
答案是第二种,RocketMQ 的 Master-Slave 模式采取的是 Slave Broker 不停的发送请求到 Master Broker 去拉取消息。
所以首先我们要明确这一点,就是 RocketMQ 自身的 Master-Slave 模式采取的是 Pull 模式拉取消息。
RocketMQ 读写分离的实现?
既然 Master Broker 接收系统的消息写入,然后同步给 Slave Broker。说白了,Slave Broker 也应该有一份一样的数据。
那么当一个消费者系统需要获取消息的时候,是从 Master Broker 获取的?还是从 Slave Broker 获取呢?
其实都不是。答案是:有可能从 Master Broker 获取消息,也有可能从 Slave Broker 获取。
(1)作为消费者的系统,获取消息的时候会先发送请求到 Master Broker 上去请求消息。
(2)Master Broker 接收到请求后,返回消息给消费者系统。
(3)Master Broker 在返回消息时,会根据当时 Master Broker 的负载情况和 Slave Broker 的同步情况,向消费者系统建议下一次拉取消息的时候是从 Master Broker 拉取还是从 Slave Broker 拉取。
举个例子,要是这个时候 Master Broker 负载很重,本身要抗大量的并发写请求,仍要从 Master 这里拉取消息加重负担,肯定是不合适的。
所以此时 Master Broker 就会建议你下一次从 Slave Broker 去拉取消息。
再举个例子,假如 Slave Broke 不知道因为什么原因,同步的特别慢。因为Slave Broker 落后 Master Broker 太多了,导致没办法从 Slave Broker 那里获取最新消息,那么下次还是只能从 Master Broker 去拉取消息。
总结一下,在写入消息的时候,通常来说肯定是选择Master Broker去写入的;但是在拉取消息的时候,有可能从Master Broker获取,也可能从Slave Broker去获取,一切都根据当时的情况来定。
如果Slave Broke挂掉了有什么影响?
上面咱们已经分析过,消息的写入肯定是全部发送到 Master Broker 上的,然后获取消息时,有可能走 Master Broker,有可能走 Slave Broker。
所以如果 Slave Broker 挂了,那么此时无论是消息的写入还是拉取,都可以继续由 Master Broke 完成,对整体运行影响不大。
只不过因为少了 Slave Broker,所有读写的压力都会集中打在 Master Broker 上,增加了 Master Borker 的负载。
如果Master Broker挂掉了该怎么办?
通过 Slave Broker 可以同步数据,尽量保证数据不丢失。但在 RocketMQ 4.5 版本之前,一旦 Master 出现故障挂掉了,Slave 没有办法自动切换成 Master。
而且虽然 Slave Broker 应该是有一份和 Master Broker 一模一样的数据,但实际上很可能有部分数据还没来得及从 Master Broker 同步过来。
所以在这种情况下,如果Master Broker宕机了,这时就得手动做一些运维操作,重新修改一些配置把 Slave Broker 调整为 Master Broker。这个过程有点麻烦而且会导致中间一段时间不可用。
由于无法实现自动 Slave 切换为 Master,在 4.5 版本之前 RocketMQ 并不是彻底的高可用模式。
基于 Dledger 实现 RocketMQ 高可用自动切换?
搞过运维的同学都知道重写配置,上线机器等等这个过程是多么蛋疼。在RocketMQ 4.5 之后,Dledger机制的出现大大改变了这种情况。
本身这个机制是基于 Raft 协议实现的,实现原理和算法思想是有点复杂的,我在后面专门写一篇文章来介绍下。
今天先介绍下如何基于 Dledger 实现 RocketMQ 的主从热切换。
简单来说,一般一个 Master Broker 会对应多个 Slave Broker,然后会在Master 和 Slave 之间进行数据同步,也就是说一份数据可以有多份副本。
当 Master Broker 挂掉了,可以通过 Dledger 技术和 Raft 协议算法进行 leader 选举,从 Slave Broker 中选出一个成为新的 Master Broker。
整个过程一般只要 10 ~ 几十秒的时间,而且一切都是自动的。
总结
消息中间件 MQ 作为解决高并发、分布式环境的利器,还有很多的内容需要我们去学习。很多工作3年的程序员提起 MQ 还是一脸茫然,因为它的本身涉及到方方面面,希望大家继续关注《从零开始消息中间件》系列。
文末福利
小伙伴可以后台回复关键字进入对应的秋招/内推/面试群,我给大家整理了各大公司的内推通道、简历模板还有历年的笔试题,大家要好好准备哦。还可以帮助大家免费修改简历、模拟面试哦~
关注公众号「Craig无忌」
创作不易,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!