教你设计一套高可用高并发、海量存储以及可伸缩的消息中间件生产架构(RocketMQ 必备)

到目前为止,我们已经基本掌握了MQ的相关核心工作原理,同时一起设计了消息路由中心 (消息中间件路由中心你会设计吗,不会就来学学)和 Broker 主从架构(消息队列Broker主从架构详细设计方案,这一篇就搞定主从架构),现在如果让你基于它的基本原理去设计一套 MQ 的生产部署架构出来,你准备怎么去思考呢?

在这套架构中,你需要着重考虑的就是高可用问题,也就是说要保证整个系统在运行过程中,其中的任何一个环节宕机都不能影响整个系统。今天我们就来打卡如何设计一套高可用的消息中间件生产部署架构。

 

NameServer 集群化,保证路由高可用

首先,我们就是需要将NameServer 集群化部署,这里建议可以部署三台机器,这样可以充分的保证我们消息路由中心的可用性,哪怕其中的两台挂了,也还有一台 NameServer 在运行,这样就能保证我们 MQ 系统的稳定性。

前面我们也知道我们的NameServer 设计采用的是Peer-to-Peer 模式,即可以支持集群化部署的,每台机器是独立运行的,他们彼此直接不直接通信。

每台NameServer 机器都拥有所有的路由信息,包括所有的 Broker 节点信息、数据信息等 ,这样只要有一台 NameServer 存活就不会影响系统的稳定性。

所以,消息路由中心 NameServer 的集群化是我们整个MQ生产部署的第一步。

 

基于Dledger 的Broker主从架构部署

上面我们已经集群部署了消息路由中心 NameServer ,接下来我们看看怎么部署 Broker集群,应该用什么方式去部署。

昨天我们知道共有两种方式,一种是手工运维,这个会造成一段时间不可用时间,而且需要该配置重启之类的,比较麻烦,另一种就是基于 Dledger 技术实现自动切换故障部署。所以我们肯定就是选择基于 Dledger 主备自动切换的功能来进行生产架构的部署。

Dledger 技术是要求至少一个 Master Broker 带有两个 Slave Broker ,这样就是三个 Broker 共同组成一个 Group ,即作为一个分组来运行,如果,Master Broker 宕机,则可以从另外两个Slave Broker 选出一个作为Master Broker对外提供服务。

同时,Master Broker 还会将数据同步给所有Slsve Broker ,这样实现了一份数据在不同的节点上有多个副本。

 

Broker 是如何同 NameServer 通信的?

前面我们分享了Broker 会像所有 NameServer 发送心跳消息告知自己还活着,同时,NameServer 每10秒检查一下有没有哪个Broker 超过了120秒还没发心跳,如果超过了就将其剔除。

但是具体的通信细节并未涉及到,今天我们就将其做一个补充讲解。

首先,Broker 和NameServer 之间是通过什么协议来通信的?HTTP协议?RPC协议还是TCP长连接。

我们这里采取的是基于 TCP 长连接方式进行通信。即Broker 会跟每个 NameServer 建立TCP 长连接,然后定时通过长连接发送消息过去。

所以,我们的NameServer 就是通过和 Broker 建立的TCP 长连接不断的收取心跳消息,然后定时检查Broker 有没有120s 都没发心跳包,这样来判断集群中有没有哪个Broker 挂掉。

 

使用MQ的系统多机器集群部署

接下来,我们肯定会有很多使用 MQ 的系统,有些系统作为生产者往我们 MQ 中发送消息,有些系统作为消费者从我们 MQ 中获取消息,而有些系统即使生产者也是消费者。

本来这个业务系统部署不应该在这里讲的,因为前面也讲了很多章节,但是这块还是有必要提一下的,其实无论是生产者系统还是消费者都是建议要多机器集群部署的,确保消费者以及生产者自身的高可用性。

因为如果一个业务系统只是部署了一台机器,而它作为生产者向 MQ 发送消息的时候,如果突然宕机了,就不能保证自己的高可用了直接影响到自身实际业务。

但是如果它是多机器集群部署的话,即使一台机器挂了,还是有其他机器能生产发送消息的,这样就能保证自己的高可用了。

如上图所示,同理,消费者系统也是一样,将其进行多机器集群部署,其中一台机器宕机,集群里其他机器一样能运行。

 

MQ 核心数据模型:Topic 到底是啥?

我们都知道生产者和消费者是往MQ 里写消息和获取消息,但是你有没有思考一个问题:

  • MQ 中的数据模型是什么?

  • 发过去的消息在逻辑上到底是放到哪儿去的,队列吗?还是什么其他的?

是 Topic ,它就是 MQ 中的核心数据模型,我们就理解为表达是 数据集合 的意思就行了。

比如,现在我们的订单系统需要将订单信息发送到 MQ 中,那么我们就得要在 MQ 中新建一个 Topic,名字起做 topic_order_info,这就是一个包含订单信息的数据集合,然后我们的订单系统所发送的消息都是会发送到 topic_order_info 这个数据集合里面。

然后,我们的仓储系统需要获取订单信息,就从MQ 的 topic_order_info 中获取就行了,这里获取到的信息都是它自己想要的订单数据。

假设你有商品数据要发到 MQ 中,你就先创建一个商品数据相关的Topic 比如topic_product_info,要获取的话就在这个topic里获取就行了。

简单总结就是,Topic就是一个数据集合,不同类型的数据就得有不同的Topic来存放;你系统要发消息还是获取消息,得先创建对应的Topic 作为数据存放集合,例如订单Topic 或者商品Topic等。

 

Topic 在 Broker集群里是怎么存储的?

通过上面我们已经知道了,生产者发送的消息是发往Topic 的数据集合中的,那么,这个Topic 是要怎么存储在 Broker 集群里面的?

现在假设我们有一个订单信息Topic,可能订单系统每天都会往里面发送几百万条订单数据,然后这些数据在 MQ 集群上还得保留好几天,那么最终可能就有几千万的数据量,这还只是一个Topic。如果有很多的 Topic呢,并且里面都有大量的数据,最终总和起来很可能就是一个很惊人的数字,这个时候,这么大量的数据本身想要存在一台机器几乎是不可能。

那一台机器存不了这么大的数据量,我们该怎么办呢?看过前面的同学应该都能猜到,那就是分布式存储

首先,我们在创建 Topic 的时候指定让它里面的数据分散到多台 Broker 机器上,比如订单Topic里面有1000 万条数据,此时有 2 台 Broker,那么就可以让每台 Broker 机器各存储 500 万条数据。这样我们就将一个Topic 中的数据分散到了多台机器进行存储了。

注意:每个 Broker 在向 NameServer 发送心跳消息时,都会告知 NameServer 自己当前的数据情况,比如有哪些 Topic 的哪些数据 在自己这里,这些也属于路由信息的一部分。

 

生产中系统如何将消息发送给 Broker的?

前面我们知道,生产者系统在发送消息之前,需要先有一个 Topic,然后在发送消息的时候你需要指定发到哪个 Topic 里面去。

既然你知道你要发送的Topic ,那么就可以和NameServer 建立一个TCP 长连接,然后定时的从它那里拉取最新的路由信息,包括集群里有哪些Broker ,有哪些 Topic ,每个 Topic 都存在哪些 Broker 上。

然后生产中系统就很自然可以通过拉取的路由信息找到自己要投递消息的Topic 分布在那几台 Broker 机器上,这个时候我们就可以依据相关负载均衡算法,选出一台 Broker 机器来,比如 round robine 轮询算法,或者 Hash 算法等,都行。至于RoketMQ 的如何选择

Broker 的算法,后面会单独再讲出来。

Broker 在收到消息之后就会存储在自己的本地磁盘中了

注意:生产者肯定是投递消息到 Master broker 的,然后Master Broker 会同步数据给他的 Slave Broker,实现一份数据多个副本,保证Master故障的时候数据不会都是,同时还可以自动将Slave 切换为 Master 继续提供服务。

 

消费者如何从 Broker 上拉取消息?

其实,消费者系统和生产者原理是类似的,它们都是会和 NameServer 建立长连接,然后拉取路由信息,接着找到自己要获取消息的 Topic 在那几台Broker 上,就可以和broker 建立长连接,从里面拉取消息了。

注意:消费者系统可能从 Master broker中拉取消息,也有可能从Slave Broker 上拉取消息,得看当时情况。

 

整体架构蓝图

通过我们上面那几点的设计,现在我们整个生产架构是实现了完全高可用的,因为:

  • NameServer 任何一台机器挂了也没事,她说集群化部署的,而且每台机器都有完整的路由信息。

  • 任何一台Broker 机器挂了也没事,Slave 挂了对整个集群影响也不是太大,挂了Master 是会基于Dledger 技术实现自动 Slave 切换为Master的。

  • 生产者系统和消费者系统随便挂了一台也没事,因为他们都是集群化部署的,其他的机器会接管工作。

同时这套架构是可以抗住高并发的,因为;

  • 假设订单系统向订单 Topic 每秒发起 10 万QPS 的写入,那么只要订单 Topic 分散在比如 5 台 Broker 上。

  • 实际上每个 Broker 会承载 2 万 QPS 写入,也就是说高并发场景下的 10 万 QPS 可以分散到多台 Broker 上扛下来。

这套架构是可以存储海量消息的,因为:

  • 所有数据都是分布式存储的。

  • 每个 Topic 数据都是存储在多台 broker 机器上的,用集群里多台 Master Broker 就足以存储海量消息。

因此,用多个 Master Broker 部署的方式,加上 Topic 分散在多台Broker上的机制,可以抗下高并发访问以及海量消息的分布式存储。

然后,每个 Master Broker 有两个 Slave Broker 结合 Dledger 技术可以实现故障时自动故障切换,实现高可用。

最后,这套架构还具备伸缩性,就是说如果要抗更高的并发,存储更多的数据,完全可以再集群里加入更多的 Broker 机器,这样就可以线性扩展集群了。

总结,今天我们一起搭建了MQ 的生产部署架构,主要从 高可用、高并发、海量存储、线性扩展方面进行讲解的,希望今天的内容对你有帮助,谢谢。

下一篇预告:rocketmq 部署方案

在公众号【架构师修炼】菜单中可自行获取专属架构视频资料,包括不限于 java架构、python系列、人工智能系列、架构系列,以及最新面试、小程序、大前端均无私奉献,你会感谢我的哈

往期精选

消息队列Broker主从架构详细设计方案,这一篇就搞定主从架构

消息中间件路由中心你会设计吗,不会就来学学

消息队列消息延迟解决方案,跟着做就行了

秒杀系统每秒上万次下单请求,我们该怎么去设计

【分布式技术】分布式系统调度架构之单体调度,非掌握不可

CDN加速技术,作为开发的我们真的不需要懂吗?

烦人的缓存穿透问题,今天教就你如何去解决

分布式缓存高可用方案,我们都是这么干的

每天百万交易的支付系统,生产环境该怎么设置JVM堆内存大小

你的成神之路我已替你铺好,没铺你来捶我

发布了29 篇原创文章 · 获赞 15 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/csdn681/article/details/103669505
今日推荐