Kafka 数据存储与清理机制:Topic、Partition、Segment与日志删除
Kafka 的底层不是把消息一条条放进传统队列而是把 Topic 的数据按 Partition 写成追加日志。理解它的存储结构才能解释为什么 Kafka 能高吞吐也能解释日志为什么可以按时间或大小清理。一句话概括Kafka 中 Topic 数据落在 Partition 上每个 Partition 又被拆成多个 Segment每个 Segment 通常包含.log数据文件、.index偏移量索引和.timeindex时间索引。分段让查找更快也让过期日志删除更方便。Topic: itheimaPartition 0Partition 1Segment 0Segment 1000.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 可以整体删除查找 offset10520定位所在 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 存储结构可以记成一句话TopicPartitionSegment.log.index.timeindexPartition 负责并行Segment 负责文件管理Retention 负责清理。