RocketMQ知识

前言

早期RocketMQ创始团队是使用ActiveMQ作为消息中间件选型的,业务随着topic和queue的增加,IO模块会遇到瓶颈;转而准备使用Kafka,但是Kafka在低延迟和可靠性方面又不能满足要求。于是就有了 支持大批量,零丢失的可用于交易系统的RocketMQ

简介

RocketMQ和大多数MQ一样,由Producer,Broker,Consumer组成

消息支持特性

消息存储

CommitLog

消息主体,元数据存储主体,消息内容不是定长,单个文件默认1G,文件名长度20位,以偏移量命名

ConsumeQueue

消息消费队列,其本质是消费消息的索引,保存指定topic下队列消息在CommitLog中的起始物理偏移量offset,消息大小size和消息Tag的HashCode值

IndexFile

提供了一种通过key或时间区间查询消息,以文件创建时间戳命名的IndexFile文件,大约能保存2000W个索引。底层存储结构为HashMap结构

RocketMQ使用混合型存储结构(多个Topic消息实体内容存储于一个CommitLog中),数据和索引分离,Producer发送消息到Broker端,同步/异步对消息进行刷盘持久化。Consumer对消息进行拉取消费,若拉取不到,等待下一次拉取,同时服务端支持等待30s,期间到达队列消息会直接返回给Consumer。

页缓存与内存映射

页缓存

OS加速对文件读写;将磁盘文件放入内存中,对磁盘文件写先对内存中映射进行写,再定时flush到磁盘;对磁盘文件读,根据页大小进行相邻数据块进行预读

MappedByteBuffer

利用NIO中FileChannel将磁盘物理文件直接映射到用户态内存地址中,Mmap方式减少两次拷贝

消息刷盘方式

通信机制

RockatMQ通过自定义消息数据结构,编/解码,底层采用Netty组件,使用Reactor模型

消息过滤

RokcetMQ在Consumer端进行消息过滤,

ConsumeQueue结构

过滤方式

负载均衡

事务消息

  1. half消息在一阶段对消费者不可见,采用修改消息Topic的方式存储消息,开启定时任务定时回查Producer的事务状态
  2. 通过OP消息表示事务消息的状态(Commit或Rollaback),Roback状态不需要做任何处理;commit操作写入Op消息时创建Half消息索引。Half消息改写Topic和Queue进行消费者消费。若事务消息没有对应Op消息,说明事务消息状态未决。需要通过回查等方式进行确定(默认最多15次)

查询数据

MessageId

消息主机地址,端口,commitlog偏移地址

MessageKey

由HashMap结构构成的IndexFile索引查询

key为 topic+#+key,然后通过Next Index解决hash冲突,最终通过 commit log offset获取消息所在位置