第 7 章 消费进度:书签记录在哪里
读到了与处理完了是两件事
消费者有“当前位置”,表示接下来取哪里;还有“已提交偏移量”,表示组恢复时从哪里继续。通常提交的是下一条要处理的记录位置。如果分区 0 的 offset 0、1、2 已经成功完成,应提交 3。
已完成:0 1 2 | 下一条:3 4 5
提交进度:3
消费者组的进度由 Kafka 管理,通常保存在内部主题 __consumer_offsets。它不是刻在每条业务记录上的“已读”标记,所以多个组能拥有不同书签。
为什么会重复
考虑以下时间线:消费者读到 offset 2;短信已成功发送;进程突然退出;offset 3 还没提交。重启后,它可能再次读到 offset 2,再发送一次短信。
如果反过来,先提交 offset 3,再发短信,进程在两步之间退出,短信就可能永远漏发。
这不是调一个超时时间就能彻底解决的问题,而是外部业务结果与 Kafka 进度之间缺少一个共同的原子提交边界。后文会讲幂等和事务。
Lag 是什么
上一章的组描述通常包含 CURRENT-OFFSET、LOG-END-OFFSET 和 LAG。可以先近似理解为“已经提交的位置”“日志末端位置”和“两者差距”。
Lag 反映偏移量距离,不等于精确的待办订单数量,也不等于等待秒数。事务、压缩和记录可见性会影响解释。更有用的是同时观察 Lag 趋势、事件时间到处理完成的延迟、处理吞吐和错误率。
练习:有意识地回放
先停止 hello-readers 组的所有消费者,再预览:
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--group hello-readers --topic hello-kafka \
--reset-offsets --to-earliest --dry-run确认只涉及本书的练习组和主题后执行:
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--group hello-readers --topic hello-kafka \
--reset-offsets --to-earliest --execute重启该组消费者,就会从最早保留位置继续。若对真实扣款业务回放,可能重新触发副作用,因此生产回放必须明确目标范围并先确保幂等。
重置成功只说明书签被修改,还应重新启动同一个组,实际核对三条中文记录确实再次读到;同时比较另一业务组的已提交位置,确认没有被一起重置。完整回放方案需要记录目标主题和分区、起止位置、操作者、业务幂等依据以及停止条件。需要独立重算又不想修改原组时,可以用新的组读取保留日志,但新增读者仍会消耗集群资源。