RocketMQ源码系列(1) — 基础架构
基础架构
我们先通过下面这张图来整体的对 RocketMQ 有一个基础架构上的认识。RocketMQ 主要有四个角色:NameServer、Broker、Producer、Consumer。
Broker
每台机器上部署的 RocketMQ 进程一般称之为 Broker,生产者向 Broker 发送消息,Broker 收到生产者的消息后存储到本地磁盘文件中,消费者从 Broker 读取消息来消费。
高并发机制
RocketMQ 单机一般 10万+ QPS,为了支撑高并发访问,例如几十万QPS,Broker 支持集群部署,这样可以把请求分散到多台 Broker 上,RocketMQ 就是通过集群化部署来抗下高并发。
海量数据存储
Broker 会收到大量消息,这些消息并不会立马被消费者消费,所以 RocketMQ 会把消息存储到本地磁盘,然后等待消费者来消费消息。MQ 可能会存储大量的消息,可能是几百万、上亿的消息,这么多消息在一台机器上肯定无法存储。基于 Broker 的集群化部署,所有的消息会分散到多台 Broker 上,然后 Broker 存储到自己机器的本地磁盘上,这样 RocketMQ 就实现了海量数据存储,其本质上是一种分布式的存储。
主从架构
如果 Broker 宕机,为了保证数据不丢失,RocketMQ 支持主从架构模式。Broker 有 Master 和 Slave 两种角色,Master Broker 收到消息后会同步给 Slave Broker,同步数据采用 Pull 模式,即 Slave Broker 不断向 Master Broker 拉取数据。部署主从后,这时如果 Master 宕机了,Slave 上有数据副本,可以保证数据不丢失,继续对外提供服务,保证了 MQ 的可靠性和高可用性。部署 Master-Slave 后,生产者将消息写入 Master Broker,然后 Slave Broker 从 Master Broker 拉取消息进行同步;而消费者则可以从 Master Broker 或者 Slave Broker 拉取消息来消费。这里面的详细机制后面再深入研究。在 RocketMQ 4.5 版本之前,Slave Broker 只是用来同步数据,尽量保证数据不丢失,但在 Master Broker 宕机后,无法自动切换为 Master。在 4.5 版本之后,RocketMQ 提供了一种 Dledger 的机制,基于 Dledger 可以实现主从自动切换的效果。Dledger 技术要求一个 Master 至少有两个 Slave,在 Master 宕机后,就从 Slave 中选举一个出来,切换成 Master。
NameServer
Broker 支持集群部署,对于生产者来说,它要将消息发送到哪个 Broker,消费者又要从哪个 Broker 获取消息呢?这就需要 NameServer 了,NameServer 是一个路由注册中心,支持 Broker 的动态注册与发现。
高可用性
要部署 RocketMQ,首先就要部署 NameServer。NameServer 也支持集群化部署,主要就是为了保证 NameServer 的高可用性。NameServer 采用 Peer-to-Peer 的模式,集群中每台 NameServer 都是独立运行,互不通信。每台 NameServer 都会有集群中所有的 Broker 信息,只要有一台 NameServer 还在运行,就可以保证 MQ 系统的稳定性。
心跳检查
Broker 注册到 NameServer 时,会与 NameServer 建立一个 TCP 长连接,然后每隔 30秒 给 NameServer 发送一个心跳告诉它自己还活着。NameServer 收到心跳后,就会更新这个 Broker 最近一次心跳的时间。NameServer 会每隔 10秒 去检查各个 Broker 最近一次心跳的时间,如果某个 Broker 超过 120秒 都没发送心跳了,就认为这个 Broker 宕掉了,然后就会从路由信息中摘除这个 Broker。
工作机制
Broker(包括 Master 和 Slave)启动时会把自己注册到所有 NameServer 上,也就是说,每个 NameServer 都会有一份集群中所有 Broker 的信息。生产者和消费者会跟 NameServer 集群中的一个 NameServer 建立 TCP 长连接,定时从 NameServer 拉取最新的路由信息,这时就可以根据要访问的 Topic,找出这个 Topic 关联的几台 Broker,再根据一定的负载均衡策略,选出其中一个 Broker。选出 Broker 后,生产者或消费者就会跟这个 Broker 建立 TCP 长连接,然后就可以通过这个 TCP 长连接来访问这个 Broker 了。
数据模型
RocketMQ 中的核心数据模型叫 Topic,表示数据集合的意思,不同类型的数据需要放到不同的 Topic 中,可以根据不同的业务场景创建不同的 Topic。一个 Topic 可能会包含很多消息,每个 Topic 的消息可以分布式存储到多台 Broker 上。每个 Broker 在发送心跳给 NameServer 时,就会上报自己包含哪些 Topic。这样生产者和消费者就可以根据要访问的 Topic 找到 Broker。