【问题标题】:Kafka docs Producer possible message lossKafka docs Producer 可能的消息丢失
【发布时间】:2021-04-22 17:08:03
【问题描述】:

我目前正在了解有关 Kafka Producer 的更多信息。我对文档中的以下段落感到有些困惑:

写入分区领导者的消息不是立即可读的 消费者不管生产者的确认设置如何。 当所有同步副本都确认写入时,则 消息被认为是已提交的,这使得它可以被阅读。 这确保消息不会因代理失败而丢失 他们已经被阅读了。请注意,这意味着消息 仅由领导者确认的(即 acks=1)可以是 如果分区领导者在副本复制之前失败,则丢失 信息。然而,这通常是一个合理的折衷方案 实践以确保在大多数情况下的耐用性,同时不影响 吞吐量太大了。

我的解释是,在领导者和复制的代理之间同步期间消息可能会丢失,即除非成功复制消息,否则不会提交消息。

我不明白 Java 应用程序如何(例如)屏蔽此消息丢失。 它在“唯一领导者”和完全复制之间收到不同的确认吗?

这在实践中通常是一个合理的折衷方案

怎么样?他们是否认为您应该记录失败的消息并手动重新排队?或者它是如何工作的?

【问题讨论】:

    标签: apache-kafka kafka-producer-api


    【解决方案1】:

    “它在 'only-leader' 和完全复制之间收到不同的确认吗?”

    领导者和副本确认之间没有区别。您只能通过其配置 acks 来控制生产者的行为。如果设置为1,它将只等待leader确认,如果设置为all,它将等待所有副本(基于主题的复制因子),然后生产者认为写入消息成功.

    如果您设置了acks=all 并且领导者和副本之间的同步失败,您的生产者将收到一个retriable 异常(“NotEnoughReplicasException”或“NotEnoughReplicasAfterAppendException”,请参阅更多详细信息here)。根据生产者配置retries,它将尝试重新发送消息。 Kafka 的构建方式期望崩溃的代理(在“短”时间内)再次可用。

    如果你设置了acks=1并且leader和replica之间的同步失败了,你的producer认为消息已经成功写入集群,它不会尝试复制消息。当然,领导者将继续将消息复制到其副本。但并不能真正保证会发生这种情况。在消息被复制之前,领导者代理本身可能会出现导致消息永远丢失的问题。

    【讨论】:

    • 因此,根据您的解释,我了解到除非您将 ack 设置为“全部”,否则无法保证交付。如果您不想丢失消息(?),我看不出不将其设置为“全部”是一个可接受的权衡。这就像一个在确认时丢失插入的数据库,我似乎根本无法接受。对我来说听起来很奇怪。您对等待所有副本确认的开销有一些见解吗?我想使用接收器连接器将数据从 REST api 管道传输到 MongoDB。
    • 注意:我可以看到这对于大数据来说是可以接受的,但是我的用例是在特定时间捕捉用户上传数据的峰值。在这种情况下,数据不应丢失,因为它涉及用户数据。似乎我需要将“acks”设置为“all”,但前提是我可以从快速 ack 回馈给客户。如果这对你有意义。似乎是一个常见的用例。
    • 我理解您对此的看法,并且您的理解是正确的,您在设置 acks=1 甚至 0 时会失去某种程度的交付保证(这将是“即发即弃”模式)。在许多使用分布式系统的大数据用例中,如果您丢失一条或另一条消息,通常不是什么大问题。如果您只对最后几分钟的数据感兴趣,那么这几分钟后丢失的几条消息将没有任何影响。
    • 虽然,在我最后一个用例中,必须不丢失任何消息,但我仍然设置 acks=1,因为我必须一次处理大量数据。根据您的集群设置、网络带宽、流量、服务器位置和其他因素,当您将 ack 从全部减少到 1 时,您将获得真正的性能优势。在我们的例子中,如果某个集群的距离约为 50 公里,则大约是 5 倍。彼此。但是,当然,如果不了解所有提到的细节,我无法就您的案例的潜在性能优势提出建议……我想您只需要对其进行测试。
    • 顺便说一句,您还可以在 Kafka 中使用“事务”来确保不会丢失任何数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 2016-03-16
    • 2020-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-30
    相关资源
    最近更新 更多