【问题标题】:Can a message loss occur in Kafka even if producer gets acknowledgement for it?即使生产者得到确认,Kafka中也会发生消息丢失吗?
【发布时间】:2020-01-19 02:32:02
【问题描述】:

Kafka doc 说:

  • Kafka 严重依赖文件系统来存储和缓存消息。
  • 现代操作系统提供了预读和后写技术,以大块倍数的形式预取数据并将较小的逻辑写入分组到较大的物理写入中。
  • 现代操作系统越来越积极地使用主内存进行磁盘缓存。现代操作系统很乐意将所有空闲内存转移到磁盘缓存中,而在回收内存时几乎没有性能损失。所有的磁盘读写都会经过这个统一的缓存
  • ...与其保持尽可能多的内存并在空间不足时将其全部刷新到文件系统中,而是将其反转。所有数据都会立即写入文件系统上的持久日志,而不必刷新到磁盘。实际上这只是意味着它被转移到内核的页面缓存中。”

进一步this article 说:

(3) 当所有同步副本都将消息应用到它们的日志时,一条消息被“提交”,并且 (4) 只要至少一个同步副本处于活动状态,任何提交的消息都不会丢失。

所以即使我使用acks=all 配置生产者(这会导致生产者在所有代理提交消息后收到确认)并且生产者收到某些消息的确认,这是否意味着他们仍然有可能丢失消息,特别是如果所有代理都关闭并且操作系统从不将提交的消息缓存刷新到磁盘?

【问题讨论】:

    标签: apache-kafka kafka-producer-api


    【解决方案1】:

    使用acks=all 并且如果主题的复制因子 > 1,仍然可能丢失已确认的消息,但可能性很小。

    例如,如果您有 3 个副本(并且全部同步),使用 acks=all,您需要同时丢失所有 3 个代理,然后它们中的任何一个有时间进行实际写入磁盘。使用acks=all,一旦所有同步副本都收到消息,就会发送确认,您可以使用min.insync.replicas=2 确保此数字保持较高。

    如果您使用rack awareness feature,则可以进一步降低这种情况的可能性(显然,代理位于不同的机架甚至更好的数据中心)。

    总而言之,使用所有这些选项,您可以充分降低丢失数据的可能性,从而使其不太可能发生。

    【讨论】:

    • (1) 这是否使 kafka 不适合无法容忍消息丢失的用例场景?或者即使在这种情况下,人们仍然可以成功使用 kafka? (2) 是否有任何其他排队系统(RabbitMQ、ActiveMQ 等)在确认后确保消息的持久性,因此不会丢失消息(至少不是由于队列服务器暂时停机。)
    • 虽然这是“可能的”,但如果您在不同数据中心的代理上至少有 3 个副本,则极不可能。这并不意味着 Kafka 不适合无法容忍数据丢失的场景。
    • 即使消息被写入磁盘,理论上你所有的broker的磁盘可能同时发生故障。但在这里,这又是极不可能发生的。
    猜你喜欢
    • 1970-01-01
    • 2017-02-28
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 1970-01-01
    • 2019-11-12
    相关资源
    最近更新 更多