Kafka 流提交偏移语义

Kafka streams commit offset semantics

我只是想确认一些我认为介于文档之间的内容。如果说 Commit 在 kafka 流中独立于 offset/message 是否已被整套处理处理应用程序拓扑的节点,但完全取决于提交间隔?换句话说,在典型的 kafka 消费者应用程序中,当一条消息被完全处理而不是仅获取时,人们会提交,在 Kafka 流中,只需获取就足以 提交间隔 到开始并提交 message/offset ?也就是说,即使那个offset/message还没有被应用拓扑的整套处理节点处理过?

或者消息是否符合提交条件,基于拓扑的整个处理节点集处理它们的事实,并且它们已准备好在主题或外部系统中发出。

从某种意义上说,这个问题可以总结为,offset/message 何时有资格在 Kafka 流中提交?是有条件的吗?如果有,条件是什么?

您确实了解 Kafka Streams 程序,即它的 Topology 我包含多个子拓扑 (https://docs.confluent.io/current/streams/architecture.html#stream-partitions-and-tasks)。子拓扑通过主题相互连接。

如果子拓扑完全处理了记录,则可以提交记录。对于这种情况,记录的中间输出在提交发生之前写入连接两个子拓扑的主题。下游子拓扑将从“连接主题”读取并提交该主题的偏移量。

提交确实仅基于 commit.interval.ms 发生。如果获取 returns 假设有 100 条记录(偏移量 0 到 99),并且当 commit.interval.ms 命中时子拓扑处理了 30 条记录,Kafka Streams 将首先确保这 30 条消息的输出被刷新到 Kafka(即 Producer.flush())并随后提交偏移量 30——其他 70 条消息仅在 Kafka Streams 的内部缓冲区中,将在提交后处理。如果缓冲区为空,则将发送新的提取。每个线程独立跟踪 commit.interval.ms,如果提交间隔已过,将提交其所有任务。

因为提交发生在子拓扑的基础上,所以可能是提交了输入主题记录,而输出主题还没有结果数据,因为中间结果还没有被下游子拓扑处理-拓扑。

您可以通过 Topology#describe() 检查您的程序结构,以查看您的程序有哪些子拓扑。

无论是使用流还是简单的消费者,关键是自动提交发生在轮询线程中,而不是单独的线程中——一批消息的偏移量仅在后续轮询中提交,并且commit.interval.ms 只是定义提交之间的最短时间,即较大的值意味着不会在每次轮询时都发生提交。

这意味着只要您不产生额外的线程,您就只会为已完全处理的消息提交偏移量,无论处理涉及什么。