kafka消息丢失问题(对中文世界资料错误的纠正)

kafka消息丢失问题

Posted by bulingfeng on August 12, 2024

简介

不得不再次感叹,每次看中文世界的文章,很多时候都是会被恶心到,因为TMD写的东西错误百出,但是就是这样的骗子文章,大多数人也会信,这些人从来没有反思过这些人说的对不对,言归正传来说下kafka消息丢失的问题把。

详细分析

消息的丢失可以从这几方面入手:

  • 生产者端发送消息丢失;
  • 消费端的数据丢失;
  • 服务器的损坏造成的数据丢失;

生产者端

生产者端可以发送消息,但是一般都采用回调的方式来做,因为这样程序就可以根据返回的ack来判断是否发送信息到了broker。

ack又可以有这几个值,ack=0,则producer发送过去消息就不用管了;ack=1,则代表发送给broker,并且还要是leader的副本接受到数据;ack=all,这样会让ISR里面的所有副本都同步到发送的这条信息,当然也包括leader副本。

这里的关键问题来了,上面所描述ack的参数指的是kafka刷写到硬盘上吗?

答案是否定的。仅仅代表是刷到了所在副本的pagecach的缓存中。不如ack=1,producer发送消息,并且回调返回发送成功,与此同时这个leader副本的机器宕机了,这个时候这个数据会丢失的,因为还没有来的即刷新数据到磁盘。

其实上面的参数只是能够在一定程度上来防止数据丢失,因为生产环境是多个物理机部署,如果副本多的情况,会分布在不同的物理机上面。所以当ack=1的时候,producer发送的消息会发送到不同的物理机上面,这样即使某个机器挂了,也不会造成影响。

至于设置的参数为何不是直接刷写到硬盘呢?其实反问下自己就知道了,如果每次都刷新到硬盘,那么速度该有多慢,即使kafka是顺序读写的。下面是官方的帖子给出来的证据:

  1. N-1 failure toleration. If the brokers are flushing records to disks asynchronously, the strongest concurrent failure Kafka can tolerate is N-1. (i.e. N-1 brokers shut down before the memory messages flush to disk). However, for some performance reasons, by default, the producer config will set “ack=1”, where the data loss can happen if the partition leader shutdown.

参考地址

消费者端

其实只要kafka的broker端的消息不丢失,其实都是问题不大的。而仅仅是consumer端的数据没有被消费到,其实可能是由于自动提交从而导致了某些数据没有消费到,然后offset就被提交了。

还有一种是手动提交(拿到数据即认为是消费了),这个时候程序报错,导致业务逻辑没有执行完整,从而在现象上看来是消息的丢失。