rocketmq删除机制源码分析总结

有次线上排查问题,发现mq硬盘满了,分析到最后发现是删太慢了导致的,分析了源码后修改了删的频率解决了。以下是我对于rocketmq删除机制的分析的结果总结,分享给大家。

ps:以下只针对commitLog文件的删除

mq删除实现原理:
scheduledExecutorService.scheduleAtFixedRate 定时任务

mq删除定时任务间隔:
cleanResourceInterval毫秒执行一次,如果cleanResourceInterval间隔内没有执行完,等执行完后立刻执行下一次,否则就是每隔cleanResourceInterval毫秒执行一次(默认10s)

mq删除执行大概步骤:
1.删除文件
2.重新删除1.没有删掉的文件

定时任务中,mq触发删除场景:
1.当前时间等于配置的删除时间 deleteWhen,默认凌晨4点,多个;分割(比如默认是04,当当前时间小时数是4的时候,为true,可以配置24小时,代表永远触发删除)
2.磁盘使用空间不足
3.手动触发,4.2版本没有该功能

./store/commitlog 空间不足:
2.1当前使用率>90%(-D"rocketmq.broker.diskSpaceWarningLevelRatio") or 当前使用率>85%(-D"rocketmq.broker.diskSpaceCleanForciblyRatio")
2.2当前使用率>diskMaxUsedSpaceRatio/100,默认75,起效取值10~95

(触发2.2场景后不执行判断)./store 空间不足:
判断逻辑同2.1和2.2,只是判断目录是./store

mq删除方法逻辑:
参数:
fileReservedTime 过期时间,默认72,单位小时
deletePhysicFilesInterval 物理删除文件的间隔时间,默认100,单位毫秒
destroyMapedFileIntervalForcibly 文件删除第一次拒绝后,所能保留的最大间隔时间,默认1000 * 120,单位毫秒
cleanAtOnce 是否是需要强制删除,当cleanFileForciblyEnable 为 true时,并且触发2.1条件时为 true,其他情况false

当满足当前时间-文件最后修改时间超过了过期时间fileReservedTime或cleanAtOnce执行删除:
一次最多删10个文件(常量写死了),for循环文件一个一个删,两个文件删除间隔deletePhysicFilesInterval,有一个删除失败后立刻结束循环。
删除执行mappedFile.destroy:
删除时如果该文件有mq线程读取or写入,第一次失败记录时间戳,保留destroyMapedFileIntervalForcibly毫秒数,超过该时间强制删除
(保留destroyMapedFileIntervalForcibly原理:mq写入或读取会给文件引用数+1,第一次执行删除文件会记录时间戳(只记一次),如果超过最大保留时间,引用数-1000,但是如果-1000后引用依旧>0,还是会失败)

删除失败可能场景:
1.mq引用(写入或读取)该文件数量始终>1000(会有相关日志记录引用数)
2.mq内存映射清理失败(会抛IllegalStateException异常,会记录日志,一般不可能)
3.文件nio close失败(会记录日志,一般不可能)
4.有其他线程(非mq)打开或引用了文件,导致mq删除失败(会记录日志,且比第三点多日志)

mq重新删除commitLog方法逻辑:
参数:redeleteHangedFileInterval 重新删除间隔,默认1000 * 120
第一次执行删除定时任务时,一定会执行,并记录时间戳,每次执行更新时间戳为当前执行时间,当当前时间-上一次重试时间戳>redeleteHangedFileInterval时执行:
取第一个commitLog文件(commitLog目录下最早创建的),判断文件是否执行过mappedFile.destroy(正常必然是执行过),为true,删除执行mappedFile.destroy。
如果执行mappedFile.destroy 失败或成功都会记录"re delete"

参考文献:

源码分析RocketMQ文件清除机制_中间件兴趣圈的博客-CSDN博客_filereservedtime rocketmq

你可能感兴趣的:(rocketmq,rocketmq,rocketmq文件删除机制,rocketmq源码分析)