CodeWalk

Kafka日志压缩(Log Compaction)

作者:Yahuda · 2026-05-30 12:55

请解释Kafka的日志压缩(Log Compaction)机制,它是如何工作的?什么场景下需要开启日志压缩?

回答

Yahuda

日志压缩定义: 一种基于Key的去重机制,在日志中只保留每个Key的最新一条消息,旧版本的相同Key消息被删除。

与普通清理的区别:

  • 普通清理(Deletion): 基于时间或文件大小删除旧Segment
  • 日志压缩(Compaction): 基于Key保留最新版本,保证Key的最终状态

工作原理:

1. 两个指针机制:

  • Cleaner Point: 已清理的位置
  • Log Head: 当前写入位置
  • 已清理区域内每个Key只保留最新值

2. 压缩过程:

  1. Kafka后台的Cleaner线程扫描老日志Segment
  2. 构建一个Map(Key→最新Offset/Value)
  3. 排除被清除的Key,生成新的Segment替换旧的
  4. 在Segment文件中写入**Tombstone(墓碑标记)**标记删除的消息

3. 压缩配置:

// Topic配置
cleanup.policy=compact
// 或同时支持delete和compact
cleanup.policy=compact,delete

// 最小/最大保留的脏消息比例
min.cleanable.dirty.ratio=0.5  // 脏数据比例超50%才触发压缩
// 压缩线程数
log.cleaner.threads=1

使用场景:

  1. 数据库变更日志(CDC): 保存每个Key的最新状态(如用户信息的变更)
  2. 配置管理: Topic存储配置变更,消费者只需知道最新配置
  3. 表状态同步: 用Kafka Topic作为两个系统的状态同步通道
  4. 恢复场景: Consumer从最早Offset消费时可以获取每个Key的最终状态

与传统数据库对比:

  • 不是完整意义上的Upsert(不支持随机更新)
  • 异步的、尽力而为的压缩
  • 最终一致,不保证实时返回最新值
  • 压缩是分批进行的,不影响实时读写