Kafka 数据存储与清理机制:Topic、Partition、Segment与日志删除

Kafka 数据存储与清理机制:Topic、Partition、Segment与日志删除

Kafka 的底层不是把消息一条条放进传统队列,而是把 Topic 的数据按 Partition 写成追加日志。理解它的存储结构,才能解释为什么 Kafka 能高吞吐,也能解释日志为什么可以按时间或大小清理。

一句话概括:Kafka 中 Topic 数据落在 Partition 上,每个 Partition 又被拆成多个 Segment;每个 Segment 通常包含.log数据文件、.index偏移量索引和.timeindex时间索引。分段让查找更快,也让过期日志删除更方便。

Topic: itheima

Partition 0

Partition 1

Segment 0

Segment 1

000.log 数据文件

000.index 偏移量索引

000.timeindex 时间索引

Topic、Partition、Segment 的关系

Kafka 的存储结构可以这样理解:

Topic ├── Partition 0 │ ├── Segment 0 │ │ ├── .log │ │ ├── .index │ │ └── .timeindex │ └── Segment 1 ├── Partition 1 └── Partition 2
层级作用
Topic业务主题,比如订单事件、用户行为
PartitionTopic 的物理分片,提高并行能力
SegmentPartition 的日志分段,便于查找和清理
.log真正保存消息数据
.indexOffset 到物理位置的稀疏索引
.timeindex时间到 Offset 的索引

Partition 是 Kafka 并行能力的基础,Segment 是 Kafka 管理磁盘文件的基础。

为什么要分段

如果一个 Partition 只对应一个巨大文件,查找和删除都会很麻烦。

分段之后有两个明显好处:

好处说明
查找更方便先定位 Segment,再通过索引定位消息
删除更方便过期数据所在的旧 Segment 可以整体删除

查找 offset=10520

定位所在 Segment

查 .index

跳到 .log 对应物理位置

这就是为什么 Kafka 的日志清理通常可以按 Segment 粒度执行,而不是一条条消息删除。

日志清理策略一:按保留时间

课件里提到第一种清理策略是按时间。消息在 Kafka 中保存超过指定时间后,会触发清理。

默认保留时间常见是 168 小时,也就是 7 天。

Segment 写入完成

等待保留时间

是否超过 retention 时间

继续保留

删除过期 Segment

这种策略适合大多数日志、行为数据、事件流水场景。业务只关心最近一段时间的数据,超过保留期就可以清理。

日志清理策略二:按存储大小

第二种策略是按 Topic 占用空间大小。当 Topic 日志文件大小超过阈值后,Kafka 会删除更旧的数据。

Topic 日志持续增长

是否超过大小阈值

继续写入

从最旧 Segment 开始删除

按大小清理通常用于控制磁盘成本。它需要结合业务可接受的数据保留范围来配置,否则可能出现数据还没来得及被下游处理就被清掉。

清理机制的工程影响

Kafka 的消息不是消费完就立刻删除。消费者只是提交自己的 Offset,消息仍然会在 Kafka 中保存到保留策略触发。

这带来两个重要影响:

影响说明
可以重复消费只要日志还在,可以重置 Offset 重新消费
磁盘要规划高吞吐 Topic 必须估算保留时间和磁盘容量

如果业务需要重新补数据,比如修复一个消费程序 bug,可以把消费者组 Offset 回退到旧位置重新消费。但前提是旧日志还没被清理。

面试回答模板

可以这样答:

Kafka 的数据是按照 Topic、Partition、Segment 三级结构存储的。Topic 会拆成多个 Partition,每个 Partition 在磁盘上又会分成多个 Segment。每个 Segment 通常包含.log数据文件、.index偏移量索引文件和.timeindex时间索引文件。分段的好处是减少单个文件大小,提高查找效率,也方便清理过期数据。Kafka 的日志清理主要有两类策略:第一是按保留时间,消息保存超过指定时间后删除,默认常见是 168 小时;第二是按 Topic 日志大小,超过阈值后删除最旧的数据。消费者提交 Offset 不代表消息立即删除,消息是否删除由日志保留策略决定。

小结

Kafka 存储结构可以记成一句话:

Topic

Partition

Segment

.log

.index

.timeindex

Partition 负责并行,Segment 负责文件管理,Retention 负责清理。