探秘 RocketMQ 消息持久化机制

RocketMQ通过消息顺序写入CommitLog,结合ConsumeQueue和IndexFile优化消费效率,利用MMPP技术减少数据拷贝,实现高性能与高可靠性的平衡。提供同步与异步刷盘策略,兼顾数据安全与性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们知道 RocketMQ 是一款高性能、高可靠的分布式消息中间件,高性能和高可靠是很难兼得的。因为要保证高可靠,那么数据就必须持久化到磁盘上,将数据持久化到磁盘,那么可能就不能保证高性能了。

RocketMQ 在兼容这两方面做的不错,先从磁盘说起,现代的磁盘都是高性能的,写速度并不一定比网络的数据传输速度慢。比如 SSD 固态硬盘在 M.2 NVMe协议下,顺序写的速度可以达到 1500 MB/s,就算是普通磁盘,如果性能比较高的话,顺序写的速度可以达到 450MB/s~600MB/s。

在顺序写的情况下是这速度,但是不人为控制的话,磁盘采用的是随机写,在随机写的情况下,磁盘的写入速度急速下降,磁盘的随机写速度可能只有几百KB/s,这远远要慢于网络传输速度,所以它并不能满足高性能的要求

RocketMQ 在持久化的设计上,采取的是消息顺序写、随机读的策略,利用磁盘顺序写的速度,让磁盘的写速度不会成为系统的瓶颈。并且采用 MMPP 这种“零拷贝”技术,提高消息存盘和网络发送的速度。极力满足 RocketMQ 的高性能、高可靠要求。

上述从硬件的角度聊聊了高性能的保证,这些咱也不懂,还是来看看 RocketMQ 持久化机制的架构图吧。

RocketMQ 存储核心架构

在 RocketMQ 持久化机制中,涉及到了三个角色:

  • CommitLog:消息真正的存储文件,所有消息都存储在 CommitLog 文件中。
  • ConsumeQueue:消息消费逻辑队列,类似数据库的索引文件。
  • IndexFile:消息索引文件,主要存储消息 Key 与 offset 对应关系,提升消息检索速度。

咱们逐一聊聊吧,CommitLog 文件是存放消息数据的地方,所有的消息都将存入到 CommitLog 文件中。生产者将消息发送到 RocketMQ 的 Broker 后,Broker 服务器会将消息顺序写入到 CommitLog 文件中,这也就是 RocketMQ 高性能的原因,因为我们知道磁盘顺序写特别快,RocketMQ 充分利用了这一点,极大的提高消息写入效率。

但是消费者消费消息的时候,可能就会遇到麻烦,每一个消费者只能订阅一个主题,消费者关心的是订阅主题下的所有消息,但是同一主题的消息在 CommitLog 文件中可能是不连续的,那么消费者消费消息的时候,需要将 CommitLog 文件加载到内存中遍历查找订阅主题下的消息,频繁的 IO 操作,性能就会急速下降

为了解决这个问题,RocketMQ 引入了 Consumequeue 文件。Consumequeue 文件可以看作是索引文件,类似于 MySQL 中的二级索引。在存放了同一主题下的所有消息,消费者消费的时候只需要去对应的 Consumequeue 组中取消息即可。Consumequeue 文件不会存储消息的全量信息,了解 MySQL 索引的话,应该好理解这里,具体存储的字段,我在上图已经标注。这样做可以带来以下两个好处:

  • 由于 Consumequeue 文件内容小,可以尽可能的保证 Consumequeue 文件全部读入到内存,提高消费效率。
  • Consumequeue 文件也是会持久化的,不存全量信息可以节约磁盘空间。

IndexFile 是 RocketMQ 为消息订阅构建的索引文件,用来提高根据主题与消息队列检索消息的速度,这个就不细说了。

RocketMQ 持久化机制原理差不多就这些了,接下来聊一聊消息数据刷盘吧。

因为操作系统 PAGECACHE 的存在,PageCache是OS对文件的缓存,用于加速对文件的读写,所以一般都是先写入到 PAGECACHE 中,然后再持久化到磁盘上。我们熟悉的其他组件,MySQL、Redis 等都是如此。RocketMQ 也不列外。

在 RocketMQ 中提供了同步刷盘异步刷盘两种刷盘方式,可以通过 Broker 配置文中中的 flushDiskType 参数来设置(SYNC_FLUSH、ASYNC_FLUSH)。

刷盘策略

异步刷盘方式(默认):消息写入到内存的 PAGECACHE中,就立刻给客户端返回写操作成功,当 PAGECACHE 中的消息积累到一定的量时,触发一次写操作,将 PAGECACHE 中的消息写入到磁盘中。这种方式吞吐量大,性能高,但是 PAGECACHE 中的数据可能丢失,不能保证数据绝对的安全

同步刷盘方式:消息写入内存的 PAGECACHE 后,立刻通知刷盘线程刷盘,然后等待刷盘完成,刷盘线程执行完成后唤醒等待的线程,返回消息写成功的状态。这种方式可以保证数据绝对安全,但是吞吐量不大

转自:https://www.cnblogs.com/jamaler/p/12664576.html

史上最强Tomcat8性能优化

阿里巴巴为什么能抗住90秒100亿?--服务端高并发分布式架构演进之路

B2B电商平台--ChinaPay银联电子支付功能

学会Zookeeper分布式锁,让面试官对你刮目相看

SpringCloud电商秒杀微服务-Redisson分布式锁方案

查看更多好文,进入公众号--撩我--往期精彩

一只 有深度 有灵魂 的公众号0.0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值