Kafka Log Compaction 是怎么工作的?
面试怎么回答
Kafka Log Compaction 按 Topic 分区和消息 Key,在后台 Segment 清理中移除旧版本,至少保留每个 Key 的最新值。它不会重排消息或修改 Offset,也不是实时发生。删除通常通过 Key 加 null Value 的 Tombstone 表达,Tombstone 只保留一定窗口,因此消费者恢复要考虑停机时长。我会同时监控 Cleaner、磁盘和恢复完整性。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
Retention 按时间删除旧消息,Compaction 却可能保留一条很老的记录。
因为它关心的不是消息年龄,而是每个 Key 的最新状态。
Log Compaction 在分区内后台清理旧版本,保证最终至少保留每个 Key 的最新值,但不承诺立即清理。
按 Key 保留最新状态
同一分区内,相同 Key 的多条记录会由 Cleaner 在后台整理,旧值可以被移除,最新值保留。它适合 CDC 状态流、缓存恢复和 Changelog,而非普通无 Key 日志。
Offset 和顺序不会重写
Compaction 删除记录但不重排剩余消息,也不会重新编号 Offset。被清理的 Offset 仍是有效位置,消费者从该位置读取时会前进到下一条存在的消息。

删除使用 Tombstone
Key 对应 null Value 通常表示删除标记。Tombstone 需要保留一段时间让消费者看到,之后才可能被 Cleaner 清理;落后太久的消费者可能错过删除语义。
清理是异步且分段的
Cleaner 按 Segment 和配置条件工作,新写入的 Head 区域不会立即压缩。生产中要监控脏数据比例、Cleaner 吞吐、磁盘和消费者恢复时间。
为什么不能只回答概念?
“误区:开启 Compaction 后 Topic 里只剩最新值”之所以常见,是因为它在理想数据和单次执行里往往说得通。但生产环境会加入数据规模、异常值、并发、版本、失败重试和下游口径,这些条件一变化,只记住术语就很容易给出错误结论。
所以我会把 按 Key 保留最新状态、Offset 和顺序不会重写、删除使用 Tombstone、清理是异步且分段的 串成一条完整链路。最终判断标准不是某个函数或配置是否出现,而是能否稳定得到可解释、可验证、可恢复的业务结果。
落地时我会检查什么?
- 输入边界:确认数据范围、时间口径、主键和异常值是否符合假设。
- 执行过程:观察分区、并行度、状态、Shuffle 或资源变化,验证方案是否真正生效。
- 输出结果:用行数、唯一性、关键指标和样本明细证明结果正确,而不是只看任务成功。
- 失败恢复:说明重跑、回滚、版本兼容和责任人,避免一次成功后无人维护。
这些检查不一定全部写进一条 SQL 或一个任务,但面试时能主动补充,说明你回答的不是背诵题,而是在描述一套可上线的工程方案。
一个典型场景
一个缓存重建消费者停机时间超过 Tombstone 保留窗口。恢复后从最早可用位置读取,已经看不到部分删除标记,于是把旧对象重新装进缓存。问题不在 Compaction 失效,而在恢复策略假设“删除标记会永久存在”。后来增加完整快照和恢复时点校验。
Compaction 保留最终状态,不替代消费者的恢复设计。