我只是想确认一下我认为在文档行之间的内容。说kafka流中的提交是否独立于偏移量/消息是否已被应用程序拓扑的整个处理节点集所处理是正确的,但仅取决于在提交间隔上?换句话说,在典型的kafka使用者应用程序中,如果在Kafka流中完全处理了一条消息而不是仅进行提取,则会提交一个消息,只需将其提取就足以使 commit interval 进入并提交该消息/偏移量?也就是说,即使该偏移量/消息尚未被应用程序拓扑的整个处理节点集合所处理?
或者基于拓扑的整个处理节点集已经处理了它们并且可以将它们准备好放入主题或外部系统的事实,因此有资格提交消息。
从某种意义上讲,这个问题可以归结为:什么时候可以抵消/发送消息,才能在Kafka流中提交?有条件吗?如果是这样,情况是什么?
答案 0 :(得分:2)
您确实了解Kafka Streams程序,即其Topology
我包含多个子拓扑(https://docs.confluent.io/current/streams/architecture.html#stream-partitions-and-tasks)。子拓扑通过主题彼此关联。
如果记录由子拓扑完全处理,则可以提交记录。对于这种情况,在提交之前,记录的中间输出将写入连接两个子拓扑的主题。下游子拓扑将从“连接主题”中读取并提交该主题的偏移量。
通勤确实仅基于commit.interval.ms
发生。如果取回返回说100条记录(偏移量0到99),并且在commit.interval.ms
命中时,子拓扑处理了30条记录,那么Kafka Streams首先会确保将这30条消息的输出刷新到Kafka (即Producer.flush()
),之后将提交偏移量30
-其他70条消息仅位于Kafka Streams的内部缓冲区中,将在提交后进行处理。如果缓冲区为空,将发送新的提取。每个线程独立跟踪commit.interval.ms
,如果超过了提交间隔,则将执行所有任务。
因为提交是基于子拓扑进行的,所以可以比输入主题记录被提交,而输出主题尚无结果数据,因为中间结果尚未由下游子拓扑处理
您可以通过Topology#describe()
检查程序的结构,以查看程序具有哪些子拓扑。
答案 1 :(得分:2)
无论使用流还是仅使用简单的使用者,关键是自动提交在轮询线程中发生,而不是在单独的线程中发生-一批消息的偏移量仅在后续轮询中提交,并且{{1 }}只是定义了两次提交之间的最短时间,即,较大的值表示不会在每次轮询中都进行提交。
含义是,只要不产生其他线程,无论处理涉及什么,您都只会提交已完全处理的消息的偏移量。