深入学习RocketMQ的底层存储设计原理

前言

RocketMQ的是一款追求低延迟的消息队列,虽然他是存储在磁盘上的,但是他的读写性能还是非常之高,本文将分析他的存储设计,看看他是从哪些方面对性能有改善。

RocketMQ存储组成

我们可以把RocketMQ的Broker理解成一个数据库一样,数据库存储功能主要是读和写的功能,RocketMQ也一样。在数据库中,我们将数据写入数据和索引中,在RocketMQ中,我们将数据写到commitlog文件和consumequeue文件。RocketMQ数据和索引默认都存储在user.home目录下的store文件夹。

从上图可以看出,在RocketMQ中,数据存储存储在commitlog文件夹,就是消息内容存储,消息内容是通过commitlog文件存储的,并且消息内容是混合存储的,里面包含了所有topic的消息数据。

而索引有两部分,一个是consumequeue, 一个是index文件夹。

consumequeue部分是先按topic,topic下按队列进行分开存储的。我们一般是按topic消费我们的消息。这个时候consumequeue就可以派上用场了。

index索引文件是存储支持时间和消息key来检索消息的索引数据。

commitlog文件结构和写操作

发送消息到broker后,broker会开始写commitlog文件。在CommitLog类有对commitlog文件的写操作。

看下CommitLog的组成,里面包含了MappedFileQueue

MappedFileQueue里面包含了文件数组,对应多个commitlog文件,每个commitlog文件默认存储1G大小的消息。

我们再看下MappedFileQueue里面真实操作文件的的对象其实是MappedFile

MappedFile的构造函数会调用init方法,里面就是通过RandomAccessFile创建commitlog的文件对象,并且将文件映射到内存MappedByteBuffer,也就是每次都是把消息先写入内存缓冲区,再写入磁盘。

发送消息的时候,其实会操作MappedFile将消息写入内存缓冲区MappedByteBuffer。这就是RocketMQ发消息快的一个原因。

最终刷新到磁盘是怎么做的呢? 会通过mappedByteBuffer.force()函数刷新到磁盘。

commitlog文件结构和读操作

读操作体现在查找消息的方法,在org.apache.rocketmq.store.CommitLog#getMessage函数。

首先是根据偏移量查找MapperFile

最终通过MapperFile查询消息内容。

consumeQueue组成以及读写操作

看到ConsumeQueue类里面的组成,和commitlog一样,同样持有了MappedFileQueue,那么读写consumeQueue,也是操作MappedFile

这样我们也能知道consumequeue的组成

需要注意的是,consumequeue不是同步构建的。RocketMQ专门设计了一个任务ReputMessageService。 他是异步将consumequeue数据构建出来,并且使用了一个异步线程FlushConsumeQueueService将consumequeu数据刷入磁盘。

也就是索引数据都是异步构建出来的。这个也是RocketMQ消息存储性能极高的原因。

总结

1、RocketMQ存储模块包含消息数据commitlog和消息索引consumequeu部分,他们都会将文件映射到内存,不会直接操作磁盘,这样做提高了IO效率。

2、消息数据comitlog是先写入内存缓存区,再异步刷新磁盘,而消息索引consumequeue是通过异步构建的

相关推荐
烛阴28 分钟前
bignumber.js深度解析:驾驭任意精度计算的终极武器
前端·javascript·后端
服务端技术栈1 小时前
电商营销系统中的幂等性设计:从抽奖积分发放谈起
后端
你的人类朋友1 小时前
✍️Node.js CMS框架概述:Directus与Strapi详解
javascript·后端·node.js
面朝大海,春不暖,花不开2 小时前
自定义Spring Boot Starter的全面指南
java·spring boot·后端
乄夜2 小时前
嵌入式面试高频(5)!!!C++语言(嵌入式八股文,嵌入式面经)
c语言·c++·单片机·嵌入式硬件·物联网·面试·职场和发展
钡铼技术ARM工业边缘计算机2 小时前
【成本降40%·性能翻倍】RK3588边缘控制器在安防联动系统的升级路径
后端
CryptoPP3 小时前
使用WebSocket实时获取印度股票数据源(无调用次数限制)实战
后端·python·websocket·网络协议·区块链
白宇横流学长3 小时前
基于SpringBoot实现的大创管理系统设计与实现【源码+文档】
java·spring boot·后端
草捏子3 小时前
状态机设计:比if-else优雅100倍的设计
后端
拉不动的猪4 小时前
安卓和ios小程序开发中的兼容性问题举例
前端·javascript·面试