【问题标题】:Ordering guarantees when using idempotent Kafka Producer使用幂等 Kafka Producer 时的排序保证
【发布时间】:2018-10-03 14:23:36
【问题描述】:

我在我的应用程序中使用 Kafka 1.0.1,并且我已经开始使用 0.11 中引入的 Idempotent Producer 功能,但在使用 Idempontent 功能时我无法理解排序保证。

我的制作人的配置是:

enable.idempotence = true

max.in.flight.requests.per.connection = 5

retries = 50

acks = all

根据文档:

重试

设置大于零的值将导致客户端重新发送发送失败并可能出现暂时错误的任何记录。请注意,此重试与客户端在收到错误后重新发送记录没有什么不同。在不将 max.in.flight.requests.per.connection 设置为 1 的情况下允许重试可能会改变记录的顺序,因为如果将两个批次发送到单个分区,并且第一个批次失败并被重试,但第二个批次成功,那么记录第二批可能会先出现。

enable.idempotence

当设置为“true”时,生产者将确保每条消息的副本都写入流中。如果为“false”,则生产者由于代理失败等原因重试,可能会在流中写入重试消息的副本。请注意,启用幂等性要求 max.in.flight.requests.per.connection 小于或等于 5,重试次数大于 0 并且 acks 必须为“全部”。如果用户没有明确设置这些值,则将选择合适的值。如果设置了不兼容的值,则会抛出 ConfigException。

我的配置似乎符合要求,但它们似乎没有对齐。

另一个与OutOfOrderSequenceException 有关的问题: 根据文档,如果我收到此异常,则意味着生产者有可能出现故障。但是,如果我的生产者配置了max.in.flight.requests.per.connection = 5,并且假设第二个请求出现了乱序异常,那么以下所有已经在运行的请求会发生什么情况?这是否意味着我肯定有问题?

【问题讨论】:

    标签: apache-kafka kafka-producer-api idempotent


    【解决方案1】:

    在KafkaProducer中启用幂等性时,顺序是有保证的。

    即使您的max.in.flight.requests.per.connection 大于或等于 1,幂等的 KafkaProducer 仍将确保在 TopicPartition 内进行排序。与max.in.flight相关的“重试”描述仅适用于禁用幂等性的情况。

    一个幂等的 KafkaProducer 使用一个内部递增的序列号来确保排序多达 5 个 in.flight 请求,如 Pull-Request #3743 中所述:

    “[...] 我们保留了 5 个旧批次的记录元数据。”

    此外,enable.idempotence 上的文档告知最多有 5 个飞行请求。否则你会得到一个ConfigException

    KAFKA-5494Design for max.in.flight > 1 with idempotence enabled. 上的相应文档中提供了更多详细信息,其中第 5 步和第 6 步将澄清您的问题:

    有了以上假设,解决方案如下:

    1. 我们跟踪发送到分区的最后一个确认序列。这会在每次成功 ack 时更新,因此应该一直在增加。

    2. 我们为一个给定分区绑定的批次跟踪下一个序列。

    3. 当批次耗尽时,我们分配了 nextSequence。我们还将 nextSequence 增加一个批次的记录数。

    4. 如果生产请求成功,我们将最后确认的序列设置为批次的最后一个序列。

    5. 如果生产请求失败,成功的飞行批次也将失败并出现 OutOfOrderSequenceException。

    6. 因此,如果批次的序列号不是最后确认的序列的后继,并且如果它失败并出现 OutOfOrderSequenceException,我们认为这是可重试的。

    7. 当一个批次重新排队时,我们会在将其插入队列之前删除生产者 ID 和序列号。

    8. 当第一个飞行批处理失败(无论出于何种原因)时,我们将 nextSequence 重置为 lastAckdSequence + 1。

    9. 因此,如果一个批次严重失败,则后续批次的序列号在重试时将不同。这很好,因为之前的失败是 OutOfSequence 异常,这绝对意味着请求被拒绝了。

    "[...] 如果我的生产者配置了 max.in.flight.requests.per.connection = 5 并且假设第二个请求出现了乱序异常,那么以下所有请求会发生什么已经在飞行中了吗?这是否意味着我肯定会出现故障?”

    如第 5 步和第 6 步中所述,所有成功的进行中的请求也将失败并返回 retriable OutOfOrderSequenceExcpetion。由于retries 大于0,幂等的KafkaProducer 将能够保持订单。

    【讨论】:

      猜你喜欢
      • 2016-05-17
      • 2019-05-23
      • 2020-09-02
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2021-11-25
      • 1970-01-01
      相关资源
      最近更新 更多