ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

RocketMQ源码解析之broker文件清理

2020-11-25 00:01:00  阅读:255  来源: 互联网

标签:MappedFile ConsumeQueue 清理 broker indexFile 源码 offset commitlog RocketMQ


原创不易,转载请注明出处

文章目录


1. broker 清理文件介绍

1.1 哪些文件需要清理

首先我们需要介绍下在RocketMQ中哪些文件需要清理,其实可以想一想,在RocketMQ中哪些文件是一直在往里面写入东西的,最容易想到的就是commitlog 了,因为在一个broker 进程中,所有的普通消息,事务消息,系统消息啥的都往这个commitlog中写,随着时间的越来越长,然后commitlog就会越积攒越多,肯定会有磁盘放不下的那一天,而且我们消息消费完成后,那些被消费完成后的消息其实作用就很小了,可能会有这么一个场景,比如说我线上出现了某个问题,我想看下关于这个问题的消息有没有被消费到,可能你会用到这个消息,但是这种问题一般就是比较紧急的,最近实效的,之前那些消息其实作用就基本没有了,所以就需要清理掉之前的消息。其实不光commitlog需要清理,还需要清理一下ConsumeQueue 与indexFile , 因为你commitlog里面的消息都被清理了,ConsumeQueue 与indexFile 再保存着之前的一些数据,就是纯粹浪费空间了。
所以说 broker 文件清理主要是清理commitlog , ConsumeQueue , indexFile

1.2 RocketMQ文件清理的机制

我们介绍下RocketMQ文件清理的机制,RocketMQ默认是清理72小时之前的消息,然后它有几个触发条件, 默认是凌晨4点触发清理, 除非你你这个磁盘空间占用到75% 以上了。在清理commitlog 的时候,并不是一条消息一条消息的清理,拿到所有的MappedFile(抛去现在还在用着的,也就是最后一个) ,然后比对每个MappedFile的最后一条消息的时间,如果是72小时之前的就把MappedFile对应的文件删除了,销毁对应MappedFile,这种情况的话只要你MappedFile 最后一条消息还在存活实效内的话,它就不会清理你这个MappedFile,就算你这个MappedFile 靠前的消息过期了。但是有一种情况它不管你消息超没超过72小时,直接就是删,那就是磁盘空间不足的时候,也就是占了85%以上了,就会立即清理。
清理完成commitlog 之后,就会拿到commitlog中最小的offset ,然后去ConsumeQueue 与indexFile 中把小于offset 的记录删除掉。清理ConsumeQueue 的时候也是遍历MappedFile ,然后它的最后一条消息(unit)小于commitlog中最小的offset 的话,就说明这个MappedFile都小于offset ,因为他们是顺序追加写的,这个MappedFile 就会清理掉,如果你MappedFile 最后一个unit不是小于offset 的话,这个MappedFile 就不删了。

2.源码解析

我们来看下源码是怎样实现的:
在broker 存储器DefaultMessageStore 启动(start)的时候,会添加几个任务调度,其中有一个就是文件清理的
在这里插入图片描述
默认是10s执行一次,可以看到它调用了DefaultMessageStore 的cleanFilesPeriodically方法
在这里插入图片描述

2.1 清理commitlog

我们先来看下关于commitlog的清理工作
在这里插入图片描述
我们看下deleteExpiredFiles 方法的实现
在这里插入图片描述
开始几个参数,一个是文件保留实效默认是72小时,你可以使用fileReservedTime来配置,一个是删除文件的间隔100ms,再就是强行销毁MappedFile的120s(这个为啥要强行销毁,因为它还害怕还有地方用着这个MappedFile,它有个专门的引用计数器,比如说我还有地方要读它的消息,这个时候计数器就是+1的),接着就是判断到没到删除的那个时间,它默认是凌晨4点才能删除
在这里插入图片描述
再接着就是看看空间是不是充足,看看磁盘空间使用占比是什么样子的
在这里插入图片描述
这里其实不光是判断 commitlog的存储区域,后面还有段判断ConsumeQueue的存储区域的,然后与这块逻辑一样,就没有放上。这里就是获取默认的最大使用占比 就是75% ,接着就是看看commitlog 存储的那地方使用了多少了,如果是使用90% 了,就设置runningFlag 说磁盘满了,立即清理设置成true,这个参数设置成true之后,就不会管你消息有没有超过72小时,如果你使用了85% 以上了,也是设置立即清理,如果超过75 % 返回true。好了,磁盘占用空间这块我们就看完了,接着看上面deleteExpiredFiles方法实现,还有一个手动清除的,这块我没有找到哪里有用到的,如果后续找到,会补充上, 判断 到了清理的点 或者是磁盘空间满了 或者是手动删除了,满足一个条件就ok了,如果是立即清除是个true,它这里这个cleanAtOnce 变量就是true了,因为前面那个强制清理是默认开启的。
接着计算了一下fileReservedTime 就是将小时转成了毫秒,为了后面好比对,最后就是调用commitlog的deleteExpiredFile 方法清理了
在这里插入图片描述
可以看到commitlog 对象调用mappedFileQueue 的deleteExpiredFileByTime 方法来处理的,这个mappedFileQueue 就是管理了一堆MappedFile
在这里插入图片描述
这里首先是拿到所有MappedFile的引用,然后就是遍历了,可以看到它这个length是-1的,也就是最后一个MappedFile 是遍历不到的,这个是肯定的,因为最后一个MappedFile肯定是在用着的,如果你来个强制清理,一下清理了,就没法提供服务了。
遍历的时候,拿到对应MappedFile 里面最后一条消息,看看它的写入时间是不是已经过了这个过期时间了,或者直接强制删除,就会执行MappedFile的销毁方法,而且带着销毁时间
在这里插入图片描述
在这里插入图片描述
这里就不详细说了,其实就是shutdown,然后过了120s后强制把引用清了,之后就是关闭channel,删除对应文件。
接着往下说,就是销毁成功了,会记录删除数量,判断删了多少了,一批是最多删10个的,这块应该是怕影响性能的,你一直删的的话,这东西很消耗磁盘性能,容易影响其他写入,读取功能,如果你销毁失败,直接就停了。最后就是将删除的这写MappedFile从MappedFileQueue中删除掉。再回到commitlog clean service 的run方法
在这里插入图片描述
我们deleteExpiredFiles 方法已经介绍完了,然后再来看看第二个方法是干嘛的,这个其实就是判断第一个MappedFile 还可不可用了,如果不可用的话,就删了,这块有可能是上面 deleteExpiredFiles 方法MappedFile销毁失败,然后设置了不可用,但是没有清理掉,所以这块再来善后下
在这里插入图片描述
在这里插入图片描述
这块就是看第一个MappedFile 还可不可用,不可用的话,就销毁掉。好了commitlog 文件清理源码就解析完成了。接下来看下这个ConsumeQueue与indexFile的清理

2.2 ConsumeQueue 与indexFile 清理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这个蓝色框里面是关于ConsumeQueue删除的,首先是获取删除间隔,然后拿到commitlog中最小的那个offset ,接着就是判断上次清理位置与最小offset 比较,如果offset 大于它上次清理的位置的话,就说明 它得把最小offset之前的清理掉。先是记录最后一次清理的offset是最小offset , 接着就是遍历所有的ConsumeQueue ,调用每个ConsumeQueue 的 deleteExpiredFile 方法来清理,我们来看下这个方法
在这里插入图片描述
CQ_STORE_UNIT_SIZE 这个就是每个unit 占20个字节,这块与它存储有关,推荐看下《RocketMQ源码解析之broker消息存储流程(Reput ConsumeQueue)》来详细了解下它是怎么存的。
在这里插入图片描述
它的删除跟commitlog 的差不多,只不过commitlog 是根据时间来判断的,它是根据commitlog 的offset 来判断的,判断要不要删除这个MappedFile,如果这个MappedFile最后一个unit 存储的offset 小于 commitlog 最小的offset 的话就要销毁了。接着就是销毁,超时时间是1分钟,最后是删除引用。
最后我们来看下 indexFile的清理工作
在这里插入图片描述
在这里插入图片描述
可以看到,先是拿第一个indexFile 看看有没有小于commitlog 最小offset 的情况发生,这里也是拿的indexFile最后一个offset 做的对比,因为这块也是按照offset大小 前后顺序处理的,最后一个的offest 肯定是这个indexFile中最大的了,如果第一个indexFile满足了的话,就会拿到所有引用,然后遍历找出符合条件的indexFile, 调用deleteExpiredFile方法遍历销毁
在这里插入图片描述
这里就是遍历销毁,然后移除对这个indexFile管理。好了,到这我们consumeQueue 与indexFile的清理工作就完事了。

总结

本文主要是介绍了RocketMQ broker 消息清理机制,介绍了主要清理哪些文件 :commitlog ,ConsumeQueue,indexFile
接着就是介绍了什么时候触发清理,比如说凌晨4点 ,磁盘没满85% 以上的话,就是清理72小时之前的,如果是满了85%就除了还在用着的那个先清10个看看, 还有就是磁盘使用空间75% 以上也是会触发的, 低于85 % 清理72小时之前的,高于85% 先清理10个文件看看,这是commitlog的清理机制,关于ConsumeQueue与indexFile的话,就是与commitlog中最小的那个offset 有关了,小于commitlog中最小offset 的那些还是要清理掉的。
最后就是分别解析了一下commitlog 文件清理,ConsumeQueue 文件清理与indexFile 文件清理。

标签:MappedFile,ConsumeQueue,清理,broker,indexFile,源码,offset,commitlog,RocketMQ
来源: https://blog.csdn.net/yuanshangshenghuo/article/details/110097932

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有