Kafka 2.2.0 消息日志清理机制:日志删除 日志压缩

Kafka将消息持久化到磁盘中的Log中,为了控制日志文件的大小就需要对消息进行清理操作。每个Log对应一个分区副本,Log可以分为多个日志分段,便于日志的清理操作。

在了解日志清理机制之前,请先了解日志存储方式

Kafka有两种日志清理策略:

  • 日志删除:按照保留策略删除日志分段
    需要将Broker端参数log.cleanup.policy设置为delete(默认值)
  • 日志压缩:根据每个消息的key进行整合,对于有相同的key的消息,只保留最后一个版本。
    需要将Broker端参数log.cleanup.policy设置为compactlog.cleaner.enable设置为true(默认值)

如果需要同时启动日志删除和日志压缩策略,可以将log.cleanup.policy设置为delete,compact

日志删除

Kafka日志管理器中有专门的任务负责周期性地检测、删除不符合条件的日志分段文件,该周期可通过参数log.rentention.check.interval.ms来配置,默认值为300000(5分钟)。

日志删除策略有3种:基于时间的删除策略、基于日志大小的删除策略、基于日志起始偏移量的删除策略。

基于时间的删除策略

日志删除任务会定期检查日志文件中是否有保留时间超出retentionMs的日志分段。retentionMs可以通过Broker端server.properties文件中的参数log.retention.hourslog.retention.minuteslog.retention.ms来配置,优先级依次递增。默认情况下只配置了log.retention.hours
Kafka 2.2.0 消息日志清理机制:日志删除 日志压缩_第1张图片
所以说,默认的retentionMs为168小时,即日志分段最多保存7天。

那么,Kafka是根据哪个时间来判断这个日志分段是否过期呢?
首先,它并不是只根据日志分段的最近修改时间lastModifiedTime)来计算,而是根据日志分段中的最大时间戳largestTimeStamp)计算的,因为最近修改时间常常会被更新。获取最大时间戳需要查询该日志分段所对应的时间戳索引文件(.timeindex文件)中最后一条索引项,若该索引项的时间戳大于0就取该值计算,否则还是取lastModifiedTime

执行日志分段的删除任务时,会首先从Log对象中维护的日志分段的跳跃表中移除需要删除的日志分段,然后将日志分段所对应的文件和索引文件添加.deleted后缀。最后转交给名称为delete-file任务来删除以.deleted为后缀的文件,执行延迟时间可通过参数file.delete.delay.ms控制,默认为1分钟。

基于日志大小

该策略会依次检查每个日志中的日志分段是否超出指定的大小(retentionSize),对超出指定大小的日志分段采取删除策略。retentionSize可通过Broker端参数log.retention.bytes来配置,单位为字节,默认值为-1,表示无穷大,该参数配置的是Log中所有日志文件的总大小,并非单个日志分段的大小。单个日志分段文件的大小限制可通过log.segment.bytes来限制,默认为1073741824,即1GB。

基于日志起始偏移量

大多数情况下,日志的起始偏移量logStartOffset( O s t a r t O_{start} Ostart)等于第一个日志分段的baseOffset( O b a s e 0 O^0_{base} Obase0)。baseOffset的值也可以通过kafka-delete-records.sh脚本发起DeleteRecordsRequest请求手动修改。

该删除策略具体是删除某日志分段的下一个日志分段的baseOffset小于等于logStartOffset的部分。例如:日志起始分段 O s t a r t = 28 O_{start} = 28 Ostart=

你可能感兴趣的:(kafka,Kafka,消息队列)