【问题标题】:Spring @Kafkalistener auto commit offset or manual: Which is recommended?Spring @Kafkalistener 自动提交偏移或手动:推荐哪个?
【发布时间】:2020-09-25 08:18:15
【问题描述】:

根据我在互联网上阅读的内容,使用 Spring @KafkaListener 注释的方法默认会在 5 秒内提交偏移量。 假设 5 秒后,偏移量已提交,但处理仍在进行中,并且由于某些问题在消费者崩溃之间,在这种情况下,重新平衡后,分区将分配给其他消费者,它将从下一条消息开始处理,因为之前的消息消息偏移量已提交。 这将导致消息丢失。

那么,我需要在处理完成后手动提交偏移量吗?推荐的方法是什么?

再次,如果处理完成,并且在提交之前,消费者崩溃了,那么如何避免消息 在这种情况下重复。

请建议避免消息丢失和重复的方法。我正在使用 Spring KafkaListener 使用默认配置。

【问题讨论】:

    标签: spring-boot apache-kafka spring-kafka


    【解决方案1】:

    与往常一样,这取决于您的用例以及您在处理过程中希望如何处理问题。使用自动提交会改变应用程序的交付语义。

    启用自动提交更像是一种“最多一次”语义,因为您将在实际处理数据之前读取数据并提交它。如果您的处理失败,则消息已经提交并且您不会再次阅读它,因此您的应用程序将“丢失”(更准确地说是您的特定 consumerGroup)。

    禁用自动提交更像是一种“至少一次”语义,因为您仅在处理数据之后才提交数据。假设您从主题中获取 100 条消息。其中 50 条消息已成功处理,您的应用程序在处理第 51 条消息时失败。现在,由于您禁用了自动提交并且仅在处理结束时提交所有消息或不提交任何消息,因此您没有提交任何 100 条消息,下次您的应用程序再次读取相同的 100 条消息时。但是,您现在已经创建了 50 条重复消息,因为它们之前已经成功处理过。

    总而言之,您需要弄清楚您的用例是否可以处理数据丢失或重复数据。如果您的应用程序是幂等的,则可以确保处理重复项。

    您在询问“如何防止数据丢失和重复”,这意味着您指的是“exactly-once-scemantics”。这是分布式流系统中的一个重要主题,如果在哪种配置下支持此功能并取决于应用程序的输出操作,您可以查看 spring-kafka 文档。

    还请查看 GaryRussell 对此post 的评论:

    “Spring 团队不建议使用自动提交;监听器容器 Ackmode(BATCH 或 RECORD)将以确定的方式提交偏移量;最新版本的框架禁用自动提交(除非特别启用)”

    【讨论】:

      【解决方案2】:
      1. 如果消费者需要 5 秒以上的时间来处理消息,那么您的代码中存在需要修复的问题。
      2. 自动提交在生产环境中存在风险,可能会导致问题场景(消息丢失等)
      3. 最好使用手动提交以获得更好的控制。
      4. 使消费者具有幂等性,这样消费者的重复消息和WIP状态就不成问题了。可能是,维护消费者数据库中的处理状态,以便如果处理完成一半,那么在消费者重新启动时,它可以清除 WIP 状态并重新处理。同样,如果处理状态为 Complete 状态,则在重新启动时它将看到 Complete 状态并简单地将重复消息提交给 Kafka。

      【讨论】:

        猜你喜欢
        • 2019-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-10
        相关资源
        最近更新 更多