本期重点内容
我们将会在本篇文章中详细的探究一下RocketMQ文件恢复机制,即RocketMQ重新启动时所涉及一系列的存储文件是如何恢复的,其中RockeMQ的重新启动涉及两个方面,一个方面是正常关闭RocketMQ后的存储文件重新恢复,另一方面是在Broker异常关闭时(宕机等情况)存储文件重新恢复。
涉及重点文件概念
在进行详细的探究源码之前,我们先来梳理几个RocketMQ中比较重要的文件,有助于更好的理解后续的源码解析部分的内容。
abort文件
abort文件是在RocketMQ启动时会创建的一个临时文件,当RocketMQ正常的关闭时,会将此文件进行删除,当RocketMQ异常关闭时,此文本得以保留,这样就能够判断RocketMQ关闭时的状态。
这种用法我们也可以在工作中尝试的使用一下。
checkpoint文件
checkpoint文件用于记录Commitlog文件、ConsumeQueue文件、indexFile文件存储消息的存储时间戳,此时间戳之前存储的数据都是可信的,表示已经刷新到磁盘存储上去了。
Commitlog文件
生产者发送过来的所有消息都会顺序的写入Commitlog文件,并按照指定的策略刷新到磁盘上面。
ConsumeQueue件
消息消费的索引文件,消费者通过读取ConsumeQueue文件获取消息的偏移量以及大小,然后去Commitlog文件获取消息,此处获取消息涉及到了随机读取。
indexFile文件
消息的索引文件,能够根据指定消息的索引key到Broker服务器上面查询到该条消息
文件恢复脉络
源码解析
DefaultMessageStore的load方法是文件恢复的入口方法,文件恢复的脉络也是经由这个方法整理而来 可以看到lastExitOK这个变量表示的意思就是abort文件是否存在,上次是否正常退出
commitlog文件加载
commitlog文件的加载,底层调用的是mappedFileQueue.load()方法进行文件的加载,ConsumeQueue文件的加载也是调用的此方法进行对应文件的加载
继续跟进load方法,加载指定目录下面的所有文件,形成一个数组,继续调用doload方法
首先将文件进行排序,然后将文件File构成一个个的MappedFile对象,放入mappedFiles中即可
cosumeQueue文件加载
按照Topic/queue的维度进行加载,一个队列queue构建一个ConsumeQueue对象并且调用logic.load()方法将该队列queue所涉及的文件构建成一个个的MappedFile,加载方法同Commilog的mappedFileQueue.load()方法一致
文件数据的确认
recover方法是进行数据恢复的主要方法,主要是确认最后写入的物理偏移量以及对应的文件,根据if分支来看Broker的正常退出与异常退出采取的数据恢复方式是不一致的。
循环迭代consumeQueue数据的恢复
数据恢复的主要逻辑就是确认该consumeQueue的物理偏移量,表示从哪个物理偏移量处写入新的数据以及将多余的文件删除
Broker正常退出时,我可能可以看到Commilog文件的恢复,是从倒数第三个文件开始进行恢复,恢复完成后设置flushedWhere和commiitWhere的全局物理偏移量,将多余的文件删除
Borker异常退出时,Commitlog文件的恢复是从倒数第一个开始进行,迭代mappedFiles集合,通过找到mappedFile中的第一条写入的消息,进行校验是否满足条件,满足条件则从这文件开始恢复,恢复完成后也是设置flushedWhere和commiitWhere的全局物理偏移量,将多余的文件删除
文末总结
本篇主要介绍了RocketMQ文件的恢复机制,其中主要涉及了commitlog以及consumeQueue两种类型文件的数据恢复,indexFile文件的数据恢复比较简单,就不过多赘述了