Kafka 数据保留:理解和管理您的事件流

通过retention.ms、retention.bytes、主题覆盖、日志压缩基础知识和磁盘监控技巧来管理Kafka数据保留。

Kafka数据保留:理解与管理事件流

Kafka数据保留回答了一个实际问题:事件流在磁盘上应保留多久,之后Kafka才能删除它们?如果设置过于宽松,代理节点可能耗尽磁盘空间;如果设置过于严格,慢速消费者可能失去重放数据的机会。

Kafka将记录存储在分区日志中。这些日志被分割成段文件,保留清理会删除旧的已关闭段。这个细节很重要,因为Kafka通常不会在记录变旧时立即逐条删除。只有当段满足配置的保留规则时,它才符合删除条件。

为什么保留设置很重要

保留是存储、重放需求和操作风险之间的权衡。

  • 存储成本:高流量主题的长时间保留会消耗大量代理磁盘。
  • 消费者恢复:保留窗口必须长于消费者最长可能的宕机或重新处理窗口。
  • 稳定性:磁盘满可能导致代理无法接受写入,并引发更广泛的集群问题。
  • 合规性:某些数据必须保留最短时间,而其他数据应尽快删除。

支付主题可能需要几天的重放历史,而开发集群中的调试日志主题可能只需要几小时。

Kafka如何删除旧数据

Kafka主题被划分为多个分区。每个分区是一个有序的仅追加日志。Kafka将新记录写入活动段,并在当前段达到配置的大小或年龄时滚动到新段。

保留按分区应用。如果设置retention.bytes=1073741824,这大约是每个分区1 GiB,而不是整个主题1 GiB。因此,一个12分区的主题在计入副本前可以保留约12 GiB。

当同时配置了基于时间和基于大小的保留时,Kafka可以在任一限制需要清理时删除符合条件的旧段。

基于时间的保留

基于时间的保留将记录保留一段配置的时间。

在代理级别,log.retention.ms为未覆盖该设置的主题设置默认值。在主题级别,retention.ms覆盖单个主题的默认值。

kafka-configs.sh --bootstrap-server localhost:9092 \
  --entity-type topics \
  --entity-name orders \
  --alter \
  --add-config retention.ms=259200000

该示例将orders主题设置为三天。使用以下命令验证:

kafka-configs.sh --bootstrap-server localhost:9092 \
  --entity-type topics \
  --entity-name orders \
  --describe

当主要需求是重放窗口时(例如“消费者必须能够从周末宕机中恢复”),使用时间保留。

基于大小的保留

基于大小的保留限制了每个分区可以保留的日志数据量。

在代理级别,log.retention.bytes设置每个分区的默认限制。在主题级别,retention.bytes覆盖单个主题的默认值。值为-1表示该设置没有大小限制。

kafka-configs.sh --bootstrap-server localhost:9092 \
  --entity-type topics \
  --entity-name high-volume-logs \
  --alter \
  --add-config retention.bytes=1073741824

这将每个分区设置为1 GiB限制。当磁盘保护比固定时间窗口更重要时,使用大小保留。注意突发性主题,因为流量峰值可能缩短有效的重放窗口。

代理默认值与主题覆盖

代理默认值位于server.properties中,适用于未设置自己保留值的主题。

log.retention.ms=604800000
log.retention.bytes=-1
log.retention.check.interval.ms=300000

更改代理默认值通常需要重启代理或动态代理配置更改,具体取决于Kafka版本和部署工具。通过kafka-configs.sh进行的主题级更改通常更安全,因为不同主题很少需要相同的保留窗口。

对于新主题,在创建时设置保留:

kafka-topics.sh --bootstrap-server localhost:9092 \
  --create \
  --topic audit-events \
  --partitions 6 \
  --replication-factor 3 \
  --config retention.ms=604800000 \
  --config retention.bytes=2147483648

对于现有主题,修改主题配置:

kafka-configs.sh --bootstrap-server localhost:9092 \
  --entity-type topics \
  --entity-name audit-events \
  --alter \
  --add-config retention.ms=1209600000

要回退到代理默认值,删除主题覆盖:

kafka-configs.sh --bootstrap-server localhost:9092 \
  --entity-type topics \
  --entity-name audit-events \
  --alter \
  --delete-config retention.ms

保留与日志压缩

Kafka清理由cleanup.policy控制。常见值为deletecompact或两者结合compact,delete

  • delete根据保留时间或大小删除旧的日志段。
  • compact保留每个键的最新值,并随时间删除该键的旧值。
  • compact,delete允许同时应用压缩和删除规则。

压缩适用于变更日志类主题,例如以客户ID为键的客户资料更新。它不能替代常规保留。墓碑记录和删除保留有其自身的时序行为,因此在依赖压缩主题进行清理之前,请先进行测试。

实用保留检查清单

从你能容忍的最长消费者宕机时间开始。如果消费者组可能离线48小时,那么24小时的保留窗口就太短了。

在更改生产主题之前估算磁盘需求:

每秒摄入速率 x 保留秒数 x 分区数 x 复制因子

这只是一个估算,因为压缩、记录大小、索引和段开销会影响实际数值。但它提供了一个有用的起点。

同时监控代理磁盘使用率、主题增长率、未同步分区和消费者滞后。磁盘压力加上滞后上升是一个警告信号,表明消费者可能超出保留窗口。

最安全的默认做法很简单:使用主题级保留,记录每个高流量主题设置的原因,并在应用到生产环境之前在预发布环境中测试较短的保留时间。