Kafka默认不永久保留数据,必须显式配置log.retention.ms(推荐唯一时间策略),清理依据段内最后消息时间戳,受延迟删除和检查间隔控制;log.retention.bytes按Partition独立计算;delete与compact策略需同时配置cleaner启用才生效。

Kafka 默认不会永久保留数据,必须显式配置保留策略,否则依赖默认值(通常是 7 天),线上环境极易因磁盘满导致写入失败。
log.retention.ms 是唯一推荐的时间配置项
不要混用 log.retention.hours、log.retention.minutes 和 log.retention.ms —— Kafka 只读取优先级最高的那个:毫秒级 > 分钟级 > 小时级。一旦同时设了 log.retention.hours=168 和 log.retention.ms=86400000(1 天),后者生效,前者被忽略,容易误判实际保留时长。
- 生产环境一律只设
log.retention.ms,比如保留 3 天:设为259200000 - Kafka 判断段是否过期,依据是该段内最后一条消息的
largestTimeStamp,不是文件修改时间或创建时间 - 即使段已过期,也不会立刻删除;受
log.segment.delete.delay.ms(默认 60000)控制,标记后至少再等 1 分钟才真正落盘移除 - 检查频率由
log.retention.check.interval.ms(默认 60000)决定,即每分钟扫描一次可删段
log.retention.bytes 按 Partition 独立生效,不是 Topic 总量
这个参数常被误解为“整个 Topic 最大占用”,实际是每个 Partition 单独计算。例如一个 24 分区的 Topic,设 log.retention.bytes=536870912(512MB),理论峰值磁盘占用可达约 12GB(未计副本),监控时必须按 Partition 维度查 kafka-log-dirs.sh 输出,不能只看 Topic 级汇总。
- 设为
-1表示不限大小,仅靠时间策略控制——线上慎用,磁盘告警风险高 - 它和
log.retention.ms是“或”关系:任一满足即触发清理,不需要两个条件同时成立 - 清理动作是整段删除,不会切片;所以实际保留大小会有波动,取决于
log.segment.bytes(默认 1GB) - 若想更精细控盘,建议把
log.segment.bytes调小(如 256MB),让段更细碎,清理粒度更可控
delete 和 compact 清理策略不能只靠 topic 创建时指定
很多人以为在 KAFKA_CREATE_TOPICS 里写了 my-topic:1:1:compact 就万事大吉,但其实 log.cleanup.policy=compact 要真正生效,还必须打开全局 cleaner:
-
log.cleaner.enable=true必须在 Broker 配置中显式开启(默认是false) - compact 只对带 key 的消息有效;key 为 null 的消息在压缩过程中会被丢弃(不是保留,是跳过)
- 如果想先压缩再裁剪过期段,用
log.cleanup.policy=delete,compact,注意顺序不影响行为,但 cleaner 会先 compact 再 apply delete - 压缩效率受
log.cleaner.min.cleanable.ratio影响(默认 0.5):只有当某个 segment 中“可被压缩掉的比例” ≥ 50% 时,cleaner 才会处理它
最易被忽略的一点:log.retention.check.interval.ms 和 log.cleaner.enable 这两个配置哪怕只漏一个,清理都会静默失效——没有报错,但磁盘持续增长,直到某天突然写不进去。











