【问题标题】:Consumer receiving messages before all replicas acknowledge to leader kafka消费者在所有副本向领导者 kafka 确认之前接收消息
【发布时间】:2020-01-30 10:56:14
【问题描述】:

假设主题分区的高水位线是 1000 和领导者,所有跟随者副本都具有完全相同的消息。在这种情况下,生产者发送带有acks = all 的消息,并且消费者正在从该主题消费。这里是否有可能在其他副本获取请求之前提供消费者获取请求?

换句话说,在acks = all 案例中,领导者是否在收到所有同步关注者的确认之前服务消费者的获取请求?

这是因为在我们的设置中,消费者在 acks=all 案例中的关注者之前收到了一条消息。

【问题讨论】:

    标签: apache-kafka kafka-consumer-api


    【解决方案1】:

    在 Kafka 中,一条消息在添加到领导代理后就可以被消费了,但如果您设置 acks=all,领导将等待所有 in-sync-replicas 复制消息。

    通常情况下,除非复制过程中出现问题,否则主题的所有副本都应该是同步副本。 (如果某些副本不同步,即使您设置了acks=all,如果您有足够的副本(min.insync.replicas),您仍然可以继续产生消息)

    min.insync.replicas:当生产者将ack设置为“all”(或“-1”)时, min.insync.replicas 指定必须的最小副本数 确认写入以使写入被视为成功。如果这 无法满足最小值,则生产者将引发异常 (NotEnoughReplicas 或 NotEnoughReplicasAfterAppend)。

    在您的情况下,如果您设置acks=all,似乎无法绕过复制过程。但是如果你不想等待复制过程,你可以设置acks=1。使用此配置,在领导者将消息写入其本地日志后,消费者可以立即使用该消息。 (followers 也会复制消息,但leader 不会等待它们)但是你应该考虑这个配置的数据丢失风险。

    acks=1 这意味着领导者会将记录写入其本地 记录,但会在不等待所有人的完全确认的情况下做出响应 追随者。在这种情况下,领导者是否应该在之后立即失败 确认记录但在追随者复制它之前 那么记录就会丢失

    【讨论】:

    • 我有另一个观察结果支持我的观点。对于复制因子 > 1 的主题,我们进行了测试以测量具有 acks = 1 和 acks = all 的消息的往返时间(client1 -> kafka -> client2 -> kafka -> client1),并观察到延迟为两种情况都一样。
    【解决方案2】:

    docs 中明确提到,当所有同步副本都收到消息时,该消息就可以使用了。

    无论生产者的确认设置如何,消费者都不会立即读取写入分区领导者的消息。当所有同步副本都已确认写入时,则认为该消息已提交,这使其可供读取。

    【讨论】:

      【解决方案3】:

      我猜您正在观察这种行为,因为您将 min.insync.replicas 保留为默认值 1。
      领导者分区包含在min.insync.replicas 计数中,因此这意味着对于min.insync.replicas = 1,只有领导者需要进行写入(然后确认生产者),然后消息可供消费者使用;它实际上并没有等待消息被复制到其他关注者,因为min.insync.replicas 上的标准已经满足。它使acks=allacks=1 相同。
      如果你增加min.insync.replicas > 1,你会看到不同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-25
        • 1970-01-01
        • 2020-09-27
        • 1970-01-01
        • 2017-08-14
        • 2020-01-10
        • 2018-09-12
        • 1970-01-01
        相关资源
        最近更新 更多