RocketMQ|RocketMQ -- 文件不一致的解决方案

前面提到了ConsumeQueue和IndexFile是通过ReputMessageService线程异步同步commitlog日志文件信息的,如果Commitlog日志文件写入成功后,Broker宕机,那就没办法进行同步了,导致Commitlog、ConsumeQueue、IndexFile文件数据不一致。那RocketMQ是怎么解决的呢?
stroe目录下的有一个文件,叫abort。
RocketMQ|RocketMQ -- 文件不一致的解决方案
文章图片

这个abort文件,在Broker启动的时候,会创建,如果是正常退出的话,那就会销毁。
所以正常情况下,abort文件只会存在运行期,停止的时候,是没有这个文件的。
RocketMQ|RocketMQ -- 文件不一致的解决方案
文章图片

当Broker启动的时候,如果没有abort文件,说明是正常退出。如果发现存在abort文件,那就是之前是异常退出的,可能Commitlog、ConsumeQueue、IndexFile文件出现数据不一致的情况,此时就需要进行修数。
stroe目录下的还有一个文件,叫checkpoint(同abort图),存储着Commitlog文件刷盘时间点、ConsumeQueue文件刷盘时间点、IndexFile文件刷盘时间点,这些信息用于异常退出时的判断处理。
加载IndexFile的时候,如果是异常退出,IndexFile文件刷盘时间点小于该索引文件最大的消息时间戳该文件将立即销毁。
对于ConsumeQueue文件来说,文件恢复机制又分为异常停止、正常停止。异常停止就是用abort文件来判断。
如果是正常停止,从倒数第三个开始恢复,不足三个的,直接第一个遍历,找到当前Commitlog日志文件的刷新指针和提交指针,并删除ConsumeQueue文件中这个指针后的所有文件。
剩下的就是通过偏移量,通过转发消息恢复ConsumeQueue文件和IndexFile文件的内容,这个步骤同上一篇。
假设有4个Commitlog日志文件,倒数第三个就是2,然后从2开始查找。由于是正常停止的,所以预留3个Commitlog日志文件来校验是不会出问题的。
RocketMQ|RocketMQ -- 文件不一致的解决方案
文章图片

如果是异常停止,直接读取最后一个文件,然后向前遍历到第一个正确存储的文件,剩下的步骤就和正常停止的差不多。
同样假设是4个Commitlog日志文件,由于是异常退出的,所以不知道在哪里出现问题,就只能从最后一个开始往前面遍历查找,直至找到正确的文件。
【RocketMQ|RocketMQ -- 文件不一致的解决方案】RocketMQ|RocketMQ -- 文件不一致的解决方案
文章图片

    推荐阅读