rocketmq消息文件(commitlog)删除策略分析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了rocketmq消息文件(commitlog)删除策略分析相关的知识,希望对你有一定的参考价值。

参考技术A

1.测试服务器偶尔出现磁盘空间不足预警。检查后发现是rocketmq消息堆积造成。
于是研究一下rocketmq消息文件删除的策略,避免再次堆积。

2.构造场景,测试源码。
参考 https://www.jianshu.com/p/3cdd58a4bba5
3.发现
对于过期文件
1)通过设置删除过期文件的时间,会在这个小时内去删除文件,每次删除10个。
相关配置参数:

2)通过设置磁盘存储空间,达到了阈值就会删除过期的文件。
相关配置参数:

对于没有过期的文件
1)磁盘存储空间达到强制清理阈值,(通过启动命令设置)

2)磁盘存储空间达到预警线,(通过启动命令设置)

3.结论
对于过期的文件,不会存在堆积的问题。出现此种情况一般是短时间大流量产生的。
为了避免生产环境流量暴增引起的短时间消息堆积。
建议业务系统加强消费能力,不要让消息堆积,消息文件不被占用就可以更安全的被删除。
fileReservedTime设置合理的时间,保持可用磁盘空间在一定程度,可以挡住短时间的流量冲击。
发生堆积时优先删除同一个磁盘空间的其它无用日志
找到消息量大的topic,动态扩容broker,update这些topic的broker

rocketMQ 删除过期文件

commitLog 删除文件的策略
指定时间到了,磁盘不足,人工删除,满足任一条件,判断文件是否过期或者磁盘不足,是则删除,一批次最多删除 10 个文件。

commitLog,consumeQueue,indexFile 的删除策略如下图:

技术图片

 

 

commitLog 尾部是有空洞的,当一个消息在当前文件放不下时,rocketmq 认为下一个文件一定能放下该消息,消息不会分隔保存。

commitLog 文件尾部存在至少 8 字节的空洞。

一般情况的尾部组成:maxBlank,BLANK_MAGIC_CODE,随机的内容

// org.apache.rocketmq.store.CommitLog.DefaultAppendMessageCallback#doAppend
if ((msgLen + END_FILE_MIN_BLANK_LENGTH) > maxBlank) {
    this.resetByteBuffer(this.msgStoreItemMemory, maxBlank);
    // 1 TOTALSIZE
    this.msgStoreItemMemory.putInt(maxBlank);
    // 2 MAGICCODE
    this.msgStoreItemMemory.putInt(CommitLog.BLANK_MAGIC_CODE);
    // 3 The remaining space may be any value
    // Here the length of the specially set maxBlank
    final long beginTimeMills = CommitLog.this.defaultMessageStore.now();
    byteBuffer.put(this.msgStoreItemMemory.array(), 0, maxBlank);
    return new AppendMessageResult(AppendMessageStatus.END_OF_FILE, wroteOffset, maxBlank, msgId, msgInner.getStoreTimestamp(),
        queueOffset, CommitLog.this.defaultMessageStore.now() - beginTimeMills);
}

 

以上是关于rocketmq消息文件(commitlog)删除策略分析的主要内容,如果未能解决你的问题,请参考以下文章

消息队列RocketMQ如何存储消息

RocketMQ的Broker是如何持久化存储消息

RocketMQ源码系列 CommitLog 存取消息源码解析

rocketMQ rocketMQ 消息队列Offset和CommitLog

rocketMQ rocketMQ 消息队列Offset和CommitLog

rocketmq笔记之文件删除