内容简介:我们知道 RocketMQ 是一款高性能、高可靠的分布式消息中间件,高性能和高可靠是很难兼得的。因为要保证高可靠,那么数据就必须持久化到磁盘上,将数据持久化到磁盘,那么可能就不能保证高性能了。RocketMQ 在兼容这两方面做的不错,先从磁盘说起,在顺序写的情况下是这速度,但是不人为控制的话,磁盘采用的是随机写,在随机写的情况下,磁盘的写入速度急速下降,
我们知道 RocketMQ 是一款高性能、高可靠的分布式消息中间件,高性能和高可靠是很难兼得的。因为要保证高可靠,那么数据就必须持久化到磁盘上,将数据持久化到磁盘,那么可能就不能保证高性能了。
RocketMQ 在兼容这两方面做的不错,先从磁盘说起, 现代的磁盘都是高性能的,写速度并不一定比网络的数据传输速度慢 。比如 SSD 固态硬盘在 M.2 NVMe协议下,顺序写的速度可以达到 1500 MB/s,就算是普通磁盘,如果性能比较高的话,顺序写的速度可以达到 450MB/s~600MB/s。
在顺序写的情况下是这速度,但是不人为控制的话,磁盘采用的是随机写,在随机写的情况下,磁盘的写入速度急速下降, 磁盘的随机写速度可能只有几百KB/s,这远远要慢于网络传输速度,所以它并不能满足高性能的要求 。
RocketMQ 在持久化的设计上,采取的是 消息顺序写、随机读的策略 ,利用磁盘顺序写的速度,让磁盘的写速度不会成为系统的瓶颈。并且采用 MMPP 这种“零拷贝”技术,提高消息存盘和网络发送的速度。极力满足 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 后,立刻通知刷盘线程刷盘,然后等待刷盘完成,刷盘线程执行完成后唤醒等待的线程,返回消息写成功的状态。这种方式 可以保证数据绝对安全,但是吞吐量不大 。
关于RocketMQ 持久化机制的分享就这些,感谢您的阅读,希望这篇文章对您的学习或者工作有一点帮助。 有收获的话,也可以帮忙推荐给其他的小伙伴,让更多的人受益,万分感谢 。
欢迎关注公众号【 互联网平头哥 】。这里有职场感悟、 Java 技术,虽然不高大上,但通俗易懂。今天最好的是明天最低的要求,愿你我共同进步。
以上所述就是小编给大家介绍的《探秘 RocketMQ 消息持久化机制》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Windows核心编程(第5版)
Jeffrey Richter、Christophe Nasarre / 葛子昂、周靖、廖敏 / 清华大学出版社 / 2008-9 / 99.00元
这是一本经典的Windows核心编程指南,从第1版到第5版,引领着数十万程序员走入Windows开发阵营,培养了大批精英。. 作为Windows开发人员的必备参考,本书是为打算理解Windows的C和C++程序员精心设计的。第5版全面覆盖Windows XP,Windows Vista和Windows Server 2008中的170个新增函数和Windows特性。书中还讲解了Windows......一起来看看 《Windows核心编程(第5版)》 这本书的介绍吧!