CommitLog文件的文件名长度为20位,左边补零,剩余为起始偏移量,比如00000000000000000000代表了第一个文件,起始偏移量为0,文件大小为1G=1073741824;当第一个文件写满了,第二个文件为00000000001073741824,起始偏移量为1073741824,以此类推。
图2 CommitLog文件
Broker收到消息后,直接追加到这个文件的末尾。
3、消息的偏移量写入磁盘文件:ConsumeQueue
我们知道每个Topic可能对应了多个Queue,那么这些Queue在Broker中是如何体现的呢?
其实在Broker中,每个Topic下的每个Queue都会对应一些列的ConsumeQueue文件。
图3 Broker本地存储文件
就是在Broker磁盘上,会有下面这种格式的一些列文件:
~/store/consumequeue/{topic}/{queueId}/{fileName}
{topic}指代的就是某个Topic,{queueId}指代的就是某个MessageQueue。
然后存储在这台Broker机器上的Topic下的一个MessageQueue,他有很多的ConsumeQueue文件,这个ConsumeQueue文件里存储的是一条消息对应在CommitLog文件中的offset偏移量。
这点比较重要,ConsumeQueue不存储真实的消息数据,只存消息数据在CommitLog文件中的偏移量。
假设有一个Topic,他有4个Queue,然后分布在两台Broker机器上,每台Broker机器会存储两个Queue。
此时生产者选择对其中一个Queue写入了一条消息,此时消息会发送到Broker上。
然后然后Broker会把这个消息写入CommitLog文件中,同时会把消息的偏移量写入两个ConsumeQueue中,ConsumeQueue0和ConsumeQueue1。它们分别对应着Topic里的Queue0和Queue1。
图4 消息偏移量写入ConsumeQueue文件中
也就是说,Topic下的Queue0和Queue1就放在这个Broker机器上,而它们每个在磁盘上对应了一个ConsumeQueue文件,所以就是Queue0对应着Broker磁盘上的ConsumeQueue0,Queue1对应着磁盘上的ConsumeQueue1。
假设Queue的名字叫做:TopicOrderInfo,Queue0的id是0,Queue1的id是1,那么此时在Broker磁盘上应该有如下两个路径的文件:
~/store/consumequeue/TopicOrderInfo/0/ConsumeQueue0文件
~/store/consumequeue/TopicOrderInfo/1/ConsumeQueue1文件
图5 ConsumeQueue本地磁盘文件
然后,当你的Broker收到一条消息写入了CommitLog之后,其实他同时会将这条消息在CommitLog中的物理位置,也就是一个文件偏移量(offset),写入到这条消息所属的Queue对应的ConsumeQueue文件中去。
ConsumeQueue文件存在的目的就是可以快速定位到消息真实的物理位置,在ConsumeQueue中存储的每条数据不只是消息在CommitLog中的offset偏移量,还包含了消息的长度,以及tag hashcode,一条数据是20个字节,每个ConsumeQueue文件保存30万条数据,所以计算下来每个文件是5.72MB。
需要注意的是每个Topic的每个Queue都对应了Broker机器上的多个ConsumeQueue文件,保存了这个MessageQueue的所有消息在CommitLog文件中的物理位置,也就是offset偏移量。
4、RocketMQ是如何提升CommitLog写入性能的?
CommitLog作为存储消息的核心所在,关乎着整个消息队列的吞吐量。那么Broker是如何提升整个过程的性能的呢?
Broker是基于OS操作系统的PageCache和顺序写两个机制,来提升写入CommitLog文件的性能的。
首先Broker是以顺序的方式将消息写入CommitLog磁盘文件的,也就是每次写入就是在文件末尾追加一条数据就可以了,对文件进行顺序写的性能要比对文件随机写的性能提升很多。
另外,消息写入CommitLog文件的时候,并不是直接写入磁盘文件的,而是先进入OS的PageCache内存缓存中,然后再由OS的后台线程选一个时间,异步化的将OS PageCache内存缓冲中的数据刷入底层的磁盘文件。
图6 异步刷盘CommitLog文件
在采用磁盘文件顺序写+OS PageCache写入+OS异步刷盘的策略,基本上可以让消息写入CommitLog的性能接近直接写入内存,所以正是如此,才可以让Broker高吞吐的处理每秒大量的消息写入。
5、异步刷盘的利弊
很多时候鱼和熊掌不可兼得,我们充分提升性能的同时,就会牺牲一些高可用性。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

分享
首先分享一份学习大纲,内容较多,涵盖了互联网行业所有的流行以及核心技术,以截图形式分享:
(亿级流量性能调优实战+一线大厂分布式实战+架构师筑基必备技能+设计思想开源框架解读+性能直线提升架构技术+高效存储让项目性能起飞+分布式扩展到微服务架构…实在是太多了)
其次分享一些技术知识,以截图形式分享一部分:
Tomcat架构解析:
算法训练+高分宝典:
Spring Cloud+Docker微服务实战:
最后分享一波面试资料:
切莫死记硬背,小心面试官直接让你出门右拐
1000道互联网Java面试题:
Java高级架构面试知识整理:
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
1713749146856)]
Java高级架构面试知识整理:
[外链图片转存中…(img-6kGzIhwg-1713749146857)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!