我花了很多时间来寻找以下问题的答案,并在这方面找到了一个帖子,但是不确定它是否适用于v0.11 +启用的consumption-transform-publish模型。
假设Kafka v1.1和三个发布者正在编写一个正在处理的“输入”主题分区。每个都发布消息的“批”,并且仅按批提交。此外,该输入分区的处理使用者必须仅转换(或不转换)整个批处理(或提交给输出主题)。但是,每个批处理消息可以与主题分区中的其他批处理消息交织。例如,由三个发布者进行的两笔记录可能看起来像这样:
P1 writes Message p1-m1
P2 writes Message p2-m1
P1 writes Message p1-m2
P1 commits
P3 writes Message p3-m1
P2 writes Message p2-m2
P2 commits.
P3 writes Message p3-m2
(P3 not yet committed.)
该分区现在看起来如下所示,其中发布者提交了p1和p2消息,尚未提交的p3消息:
Offset 1: p1-m1
Offset 2: p2-m1
Offset 3: p1-m2
Offset 4: p3-m1 not committed
Offset 5: p2-m2
Offset 6: p3-m2 not committed
处理消费者仅轮询已读的已提交消息,因此从偏移量1到3接收消息。它(从数据中)识别出它有一个完整的批次p1和一个不完整的批次p2。它转换P1记录,在输出主题上开始新事务,写入输出主题,通过sendOffsetsToTransaction从输入主题分区传递偏移量 1和3 并提交批次。
然后P3提交-因此现在所有消息都已提交-但是...。消费处理器此时决定离开,不使用消费偏移2。
会发生什么?一方面,我们必须将每个消耗偏移传递给sendOffsetToTransaction,这意味着每个偏移都被独立标记为已提交消耗。如果是这样,那么这似乎意味着下一个访问输入分区的使用者将在偏移量2、4、5和6处轮询并接收消息,对吗?
还是因为在处理偏移量2之前提交了偏移量3而导致偏移量2的消息丢失了?如果是这样,那么在调用sendOffsetsToTransaction的调用中必须传递每个消耗偏移量的原因是什么-当仅传递最后一个偏移量就足够了吗?