RocketMQ基本原理!

总体架构图

img

零拷贝

零拷贝技术是一个思想,指的是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另一个特定区域。

  • RocketMQ内部使用基于mmap实现的零拷贝,用来读写文件。

mmap():

mmap(memory map)是一种内存映射文件的方法。

  • 即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。

简单地说就是内核缓冲区和应用缓冲区共享,从而减少了从读缓冲区到用户缓冲区的一次CPU拷贝。

消息存储

CommitLog:

CommitLog,消息存储文件,所有主题的消息都存储在 CommitLog 文件中。

业务系统向 RocketMQ 发送一条消息,最终这条消息会被持久化到CommitLog文件。

一台Broker服务器只有一个CommitLog文件(组),RocketMQ会将所有主题的消息存储在同一个文件中,这个文件中就存储着一条条Message,每条Message都会按照顺序写入。

img

ConsumeQueue:

它是为了高效检索主题消息的。

通过ConsumerQueue可以知道消息的长度和偏移量,那么查找消息就比较容易了。

消息偏移量的差值等于 = 消息长度 * 队列长度

Index:

除了通过消息偏移量来查找消息的方式,还提供了其他几种方式可以查询消息:

  • 通过Message Key查询
  • 通过Unique Key查询
  • 通过Message Id查询

Message Key和Unique Key都是在消息发送之前,由客户端生成的。

可以自己设置,也可以由客户端自动生成,Message Id是在Broker端存储消息的时候生成。

消费方式

RocketMQ消费方式有PUSH与PULL两种,但实现机制实为 PULL 模式

PUSH 模式是一种伪推送,是对 PULL 模式的封装,每拉去一批消息后,提交到消费端的线程池(异步),然后马上向 Broker 拉取消息,即实现类似 的效果

img

拉取式消费(Pull Consumer):

Pull指:由消费者客户端主动向消息中间件拉取消息

推动式消费(Push Consumer):

Push指:由消息中间件主动地将消息推送给消费者

  • 采用Push方式,可以尽可能实时地将消息发送给消费者进行消费

长轮询:

在PULL模式下为了保证消费的实时性,采起了长轮询消息服务器拉取消息的方式,每隔一定时间客户端向服务端发起一次请求

  • 长轮询还是由Consumer发起的,因此就算Broker端有大量数据也不会主动推送给Consumer

通信机制

通信架构图

img

基本通讯流程如下:

  • Broker启动后需要完成一次将自己注册至NameServer的操作,随后每隔30s时间定时向NameServer上报Topic路由信息。
  • 消息生产者Producer作为客户端发送消息时候,需要根据消息的Topic从本地缓存的TopicPublishInfoTable获取路由信息。
    • 如果没有则更新路由信息会从NameServer上重新拉取,同时Producer会默认每隔30s向NameServer拉取一次路由信息。
  • 消息生产者Producer根据获取的路由信息选择一个队列(MessageQueue)进行消息发送。
    • Broker作为消息的接收者接收消息并落盘存储。
  • 消息消费者Consumer根据获取的路由信息,并再完成客户端的负载均衡后,选择其中的某一个或者某几个消息队列来拉取消息并进行消费。

为了实现客户端与服务器之间高效的数据请求与接收:

  • RocketMQ-Remoting包自定义了通信协议并在Netty的基础之上扩展了通信模块。