深入学习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是通过异步构建的

相关推荐
2402_8575893620 分钟前
Spring Boot新闻推荐系统设计与实现
java·spring boot·后端
J老熊28 分钟前
Spring Cloud Netflix Eureka 注册中心讲解和案例示范
java·后端·spring·spring cloud·面试·eureka·系统架构
Benaso31 分钟前
Rust 快速入门(一)
开发语言·后端·rust
sco528232 分钟前
SpringBoot 集成 Ehcache 实现本地缓存
java·spring boot·后端
我爱学Python!34 分钟前
面试问我LLM中的RAG,秒过!!!
人工智能·面试·llm·prompt·ai大模型·rag·大模型应用
OLDERHARD1 小时前
Java - LeetCode面试经典150题 - 矩阵 (四)
java·leetcode·面试
原机小子1 小时前
在线教育的未来:SpringBoot技术实现
java·spring boot·后端
吾日三省吾码1 小时前
详解JVM类加载机制
后端
努力的布布1 小时前
SpringMVC源码-AbstractHandlerMethodMapping处理器映射器将@Controller修饰类方法存储到处理器映射器
java·后端·spring
PacosonSWJTU1 小时前
spring揭秘25-springmvc03-其他组件(文件上传+拦截器+处理器适配器+异常统一处理)
java·后端·springmvc