✅115、当Broker上的数据存储超过一定时间之后,磁盘数据是如何清理的
当Broker上的数据存储超过一定时间之后,磁盘数据是如何清理的?
上一次我们基本讲完了broker收到数据之后是如何把消息写入到磁盘文件里去的,如下图所示

那么今天我们就来探讨另外一个问题,就是broker不停的接收数据,然后磁盘上的数据越来越多,但是万一磁盘都放满了,那怎么办呢?
所以今天就要来讲一下,这个broker是如何把磁盘上的数据给删掉的。
先简单给大家说一下,其实默认broker会启动后台线程,这个后台线程会自动去检查CommitLog、ConsumeQueue文件,因为这些文件都是多个的,比如CommitLog会有多个,ConsumeQueue也会有多个。
然后如果是那种比较旧的超过72小时的文件,就会被删除掉,也就是说,默认来说,broker只会给你把数据保留3天而已,当然你也可以自己通过fileReservedTime来配置这个时间,要保留几天的时间。
这个定时检查过期数据文件的线程代码,在DefaultMessageStore这个类里,他的start()方法中会调用一个addScheduleTask()方法,里面会每隔10s定时调度执行一个后台检查任务,我们看下面的源码片段。

上面就可以看到了,其实他是每隔10s,就会执行一个调度任务
这个调度任务里就会执行DefaultMessageStore.this.cleanFilesPeriodically()方法,其实就是会去周期性的清理掉磁盘上的数据文件,也就是超过72小时的CommitLog、ConsumeQueue文件,如下图所示。

接着我们具体看看这里的清理逻辑,他其实里面包含了清理CommitLog和ConsumeQueue的清理逻辑,如下面源码片段。

在清理文件的时候,他会具体判断一下,如果当前时间是预先设置的凌晨4点,就会触发删除文件的逻辑,这个时间是默认的;或者是如果磁盘空间不足了,就是超过了85%的使用率了,立马会触发删除文件逻辑。
上面两个条件,第一个是说如果磁盘没有满 ,那么每天就默认一次会删除磁盘文件,默认就是凌晨4点执行,那个时候必然是业务低峰期,因为凌晨4点大部分人都睡觉了,无论什么业务都不会有太高业务量的。
第二个是说,如果磁盘使用率超过85%了,那么此时可以允许继续写入数据,但是此时会立马触发删除文件的逻辑;如果磁盘使用率超过90%了,那么此时不允许在磁盘里写入新数据,立马删除文件。这是因为,一旦磁盘满了,那么你写入磁盘会失败,此时你MQ就彻底故障了。
所以一旦磁盘满了,也会立马删除文件的。
在删除文件的时候,无非就是对文件进行遍历,如果一个文件超过72小时都没修改过了,此时就可以删除了,哪怕有的消息你可能还没消费过,但是此时也不会再让你消费了,就直接删除掉。
这就是RocketMQ的一整套文件删除的逻辑和机制。