Skip to content

kafka保证消息不丢失

Kafka 只对“已提交”的消息(committed message)做有限度的持久化保证。

生产者端消息丢失

生产者发送消息的时候,如果没有发到 kafka 导致消息丢失(网络抖动),其实这并不是 kafka 的原因。

kafka 能保证已经提交到 borker 的数据,不会丢失。

默认生产者发数据,采用 send(msg)发数据,这样发数据之后生产者并不知道是否发送成功。

最好使用 producer.send(msg, callback) 发数据,这样通过callback能够清楚的知道消息是否发送成功。

消费者端消息丢失

Consumer 端丢失数据主要体现在要消费的数据丢了。

image.png

Consumer 有个 offset 的概念,记录了消费 topic 数据的位置。

消费者消费消息丢失数据解决有两种情况:

  1. 先消费数据,再更新 offset。

    这样会导致重复消费,比如消费数据完成了,但是更新 offset 失败了。下次消费的时候还从未更新的 offset 开始消费,导致数据重复消费。

  2. 在多线程异步消费消息的情况。

    在多线程情况下,假如有线程消费数据处理失败,而 offset 已经更新,便会导致消息丢失。

    造成这样的原因是因为消息配置了自动提交,取消自动提交改为手动提交即可。

消费者端解决消息丢失很容易,但是同时会带来消息重复消费的问题。

参数配置

生产者参数

  • acks = all

    设置为 all,表示所有leader和在LSR副本中的副本收到消息才算已提交

  • retries

    这里设置的是生产者生产消息的重试次数,当设置 > 0时,发送消息如果发生网络波动,生产者可以重试消息发送,避免消息丢失。

Broker端参数

  • unclean.leader.election.enable = false

    LSR副本集合以外的副本是否有资格竞选分区的 Leader,一般设置为 false,防止数据丢失

    如果某个 broker 落后原先的 leader 数据太多(LSR副本集合以外的副本),竞选为leader 之后会导致集群的数据丢失一部分。因为生产者发数据不保证LSR集合以外的副本收到数据。

  • replication.factor >= 3

    副本数量,将数据多保存几份,防止数据丢失。

  • min.insync.replicas > 1

    控制写入的消息最少写入几个副本算完成,但是也不建议设置为和副本数一致。这样假如有一个副本挂掉就会导致数据写入不成功。

    推荐设置成 replication.factor = min.insync.replicas + 1。

消费者参数

  • enable.auto.commit

    消息自动提交,最好不要设置为 true,这样可能导致消息丢失。

    最好设置为 false,然后消费数据后手动提交。