Apache kafka 融合云上的ApacheKafka——分区主题和消费者延迟中的非相干偏移

Apache kafka 融合云上的ApacheKafka——分区主题和消费者延迟中的非相干偏移,apache-kafka,apache-kafka-streams,spring-cloud-stream,confluent-platform,confluent-cloud,Apache Kafka,Apache Kafka Streams,Spring Cloud Stream,Confluent Platform,Confluent Cloud,在融合云上使用卡夫卡时,我发现了一种奇怪的行为。我创建了一个具有默认分区值的主题:6 我的系统由一个Java Producer应用程序和一个Kafka Streams应用程序组成,前者向该主题发送消息,后者从中读取消息并对每条消息执行操作 ----------------------- -------- ----------- | Kafka Java Producer | ----> | topic | ----> | KStr

在融合云上使用卡夫卡时,我发现了一种奇怪的行为。我创建了一个具有默认分区值的主题:6

我的系统由一个Java Producer应用程序和一个Kafka Streams应用程序组成,前者向该主题发送消息,后者从中读取消息并对每条消息执行操作

-----------------------          --------            -----------
| Kafka Java Producer |  ---->  | topic | ---->      | KStream |
-----------------------          --------            -----------
目前,我只启动Kafka Streams应用程序的一个实例,因此消费者组有一个成员

这是我观察到的:

  • 制作人发送一条消息,并将其记录在事件主题中,偏移量为0
  • 消息到达了KStream,正在正确处理,正如我在KStream日志跟踪中看到的:
  • KStream

    events.foreach { key, value ->
        logger.info("--------> Processing TimeMetric {}", value)
        //Store in DB
    
    日志

    [-StreamThread-1]持续时间$$EnhancerBySpringCGLIB$$e72e3f00:---------->处理事件{..

  • 在Confluent Cloud consumer lag中,我可以看到所有消费者组及其状态。KStream有一个名为
    events-processor-19549050-d8b0-4b39…
    。如前所述,该组只有一个成员(KStream的唯一实例)。但是,如果显示该组位于分区2中的一条消息后面。此外,请注意,当前偏移量似乎为1,结束偏移量为2):
  • 如果我在producer中发送另一条消息,它将再次记录在主题中,但这次是偏移量为2而不是1的
  • 消息到达KStream并再次正常处理:
  • [-StreamThread-1]uration$$EnhancerBySpringCGLIB$$e72e3f00:---------->处理事件{

  • 回到消费者群体的消费者滞后,它仍然落后一条信息,仍然有一些奇怪的偏移(当前3,结束4):
  • 虽然处理过程似乎很好,但上面显示的状态没有多大意义。您能否解释一下原因:

  • 消息偏移量增加+2而不是+1
  • 即使消费者群体正确处理了信息,他们似乎仍落后1条信息

  • 对于第一个问题,有两种可能性(尽管通过阅读第二个问题,您似乎正在使用事务):

    • 如果没有使用一次语义,则制作人可能会发送多条消息,因为无法控制之前发送的内容。这样,卡夫卡默认的至少一次语义可能会因为这些重复消息而增加偏移量>+1

    • 如果您只使用一次语义或事务,则事务的每个事件都会在主题中写入一个标记,用于内部控制。这些标记会导致+2增加,因为它们也存储在主题中(但消费者会避免)。此外,还有一些关于此行为的信息:

      生产者发起提交(或中止)后,协调器 开始两阶段提交协议

      在第一阶段,协调器将其内部状态更新为 “准备提交”并在事务日志中更新此状态。一次 完成后,无论发生什么情况,都将保证提交事务 什么

      然后,协调器开始第2阶段,在该阶段写入事务 将标记提交到主题分区,主题分区是 交易

      这些事务标记不向应用程序公开,而是 由处于read_committed模式的使用者用于从中筛选消息 中止的事务,并且不返回作为打开的一部分的消息 事务(即日志中的事务,但没有 与之关联的事务标记)

      写入标记后,事务协调器将标记 事务处理为“完成”,生产商可以开始下一个 交易

    一般来说,您不应该关心偏移量,因为它不是一个确定的查找指南。例如,重试、重复或事务标记会使偏移量与您期望的制作人的偏移量不同,但您不应该担心它;您的消费者会,他们只会关心“真实”消息

    关于问题2,这是一个已知的问题:

    引用jira的话:

    当使用编写Kafka Streams应用程序的输入主题时 事务,Kafka Streams不提交“endOffset”,而是提交“endOffset” -1“如果到达主题结尾。原因是主题中最后一条“消息”的提交标记;Streams commit“偏移量” 最后处理的消息加上1“,并且不考虑提交标记 帐户

    这不是一个正确性问题,而是当检查消费者滞后时 通过bin/kafka-consumer.group.sh,滞后显示为1而不是0—— 从消费者群体工具的角度来看,什么是正确的


    希望有帮助!

    你猜对了,我使用的是精确的语义。非常感谢你的详细解释和参考资料,这让我发疯;-)很高兴它帮助了我,伙计!这是一个已知的问题: