第 9 / 19 篇

第 8 章 数据保存多久:消费和删除彼此独立

保留策略

Kafka 通常按时间或大小保留日志,清理由后台按日志段推进。retention.ms 表示时间策略,retention.bytes 是每个分区的大小策略;设置了两者时,任一条件都可能推动旧日志段清理。

例如,为 orders 设置七天时间保留:

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

这里 604800000 毫秒等于七天。它不是保证每条记录精确存在七天的计时器。段滚动、检查周期、时间戳等都会影响实际清理时点。消费者落后太久时,想读的位置可能已被删除。

日志压缩

cleanup.policy=compact 用于按 Key 保留最新状态的场景,例如用户资料变更流。压缩在后台运行,不会立即变成“每个 Key 恰好一条”。删除语义通常用相同 Key、Value 为 null 的墓碑记录表达;墓碑也有自己的保留和清理条件。

订单创建、支付、退款是一串有价值的历史事实,随意只保留订单最后一次事件,可能破坏审计和重算。需要完整过程时,先考虑按时间保留事件流;需要状态视图时,再设计压缩主题。

配置压缩不等于清理已经发生

可以为状态视图单独建立一个练习主题,不要直接改变保存完整订单历史的 orders:

bin/kafka-topics.sh --bootstrap-server localhost:9092 \
  --create --topic order-state --partitions 1 --replication-factor 1 \
  --config cleanup.policy=compact
bin/kafka-configs.sh --bootstrap-server localhost:9092 \
  --entity-type topics --entity-name order-state --describe

读回 cleanup.policy=compact 证明配置已生效,不证明后台清理器已经去掉某条旧值。本轮实验仅核对保留和压缩配置,未通过加速段滚动观察物理删除或墓碑清理。压缩可能保留同一 Key 的多个版本一段时间,offset 也不会被重新连续编号;消费者必须能容忍位置空洞。对重要业务,应另行验证清理延迟、恢复窗口与状态重建。

粗算磁盘

假设平均每秒 1,000 条,每条序列化后约 1 KB,保存七天:原始写入约 1 MB/秒,一天约 86.4 GB,七天约 604.8 GB;三个副本约 1.81 TB。这里用十进制单位估算。

真实容量还要考虑压缩率、Key 与协议开销、索引、峰值、故障副本恢复和磁盘余量。别把这道估算题当成采购结论。监控磁盘增长速度,比只看配置更可靠。

本章自测:某组把所有消息读完,会释放主题磁盘吗?不会。删除主要由保留、压缩或显式管理操作决定。