【问题标题】:Spring-Kafka: Impact of Consumer Group Rebalancing on Stateful RetrySpring-Kafka:消费者组再平衡对有状态重试的影响
【发布时间】:2021-11-29 11:57:02
【问题描述】:

如果将SeekToCurrentErrorHandler 与有状态重试一起使用,这样每次重试都会从代理轮询消息,那么在很长的重试周期内,消费者组重新平衡可能会导致分区被重新分配给另一个消费者。因此,有状态的重试周期/尝试将被重置,因为新的消费者不知道重试的状态。

举个例子,如果重试的最大周期是 24 小时,但消费者组重新平衡平均每 12 小时发生一次,那么重试永远不会完成,并且消息(及其后面的消息)最终会从一旦超过保留期,主题。 (假设这次可重试异常的原因没有解决)。消息不会像预期的那样在 24 小时后在 DLT 上结束,因为重试不会因重置而用尽。

我假设即使消费者通过重新轮询消息来重试,也不能保证在重新平衡之后该消费者将保留对该分区的分配。还是我们可以确信,只要这个消费者实例还活着,它通常会保留对它正在轮询的分区的分配?

是否有关于使用有状态重试来解决此问题的最佳实践/指南?

无状态重试意味着任何超过轮询超时的总重试时间都会导致重新平衡和重复消息传递。为了避免这种情况,重试时间必须非常有限。或者是否允许这样做,确保消费者对消息进行重复数据删除,以便可以接受重复消息并且可以配置长时间运行的无状态重试?

启用重试时间(例如,为了满足在此期间不可用的服务)使用重试主题是唯一安全且稳定的选择吗?

谢谢, 抢。

【问题讨论】:

    标签: apache-kafka kafka-consumer-api spring-kafka


    【解决方案1】:

    有状态重试的重点是避免重新平衡;没有它,消费者将被延迟到所有重试尝试延迟的总和。

    但是,现在已弃用侦听器适配器中的重试(包括有状态重试),因为错误处理程序现在可以执行 RetryTemplate 可以执行的所有操作(回退、异常分类等)。

    使用有状态重试(或错误处理程序中的回退),最长回退必须小于max.poll.interval.ms

    坦率地说,24 小时后退是荒谬的 - 最好只是停止容器并在一天后重新启动它。

    【讨论】:

    • 谢谢加里。我的问题是一个冗长而漫无边际的问题。我想更简洁地问一下主要问题:如果一个消费者实例正在执行有状态重试,并且一个新的消费者实例被添加到消费者组中导致重新平衡,那么同一个消费者实例是否有保证,或者可能,或者机会?将继续轮询消息(并因此跟踪有状态的重试周期/尝试)?
    • 添加一个新的消费者只会在重试退避超过max.poll.interval.ms时导致重新平衡,这是你不应该做的。不能保证;但是,您可以使用自定义 ConsumerPartitionAssignor;还有一些“粘性”转让人试图保留现有状态。正如我所说,有状态重试已被弃用。不要使用它。
    • 是的,我没有使用 RetryTemplate。我正在使用带有 FixedBackOff 的 SeekToCurrentErrorHandler。您的文档状态:“不再需要通过侦听器适配器重试配置使用有状态重试。您可以通过错误处理程序的适当配置提供相同的功能”因此我一直在描述它作为有状态重试与其相同的功能(在重试之间从代理重新轮询,跟踪重试尝试/周期),作为将其与无状态重试区分开来的一种手段。也许我应该将其描述为错误处理程序退避重试。
    • 是的;有状态重试是RetryTemplate 的一项特定功能,因此在这种情况下使用该术语会造成混淆。
    猜你喜欢
    • 2019-08-08
    • 2020-06-30
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-19
    相关资源
    最近更新 更多