即使生产者得到确认,Kafka 中也会发生消息丢失吗?

Mah*_*aha 5 apache-kafka kafka-producer-api

卡夫卡医生说:

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

进一步这篇文章说:

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

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

Mic*_*son 8

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

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

如果您使用机架感知功能,您可以进一步减少这种情况的可能性(显然代理实际上位于不同的机架甚至更好的数据中心)。

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