✅Kafka如果丢消息了,可能的原因是什么?

✅Kafka如果丢消息了,可能的原因是什么?

典型回答

✅Kafka如何保证消息不丢失?

先看上面的文章,然后再看本文!!!

看完Kafka如何保证不丢消息之后,那么反过来想,就知道如果消息丢了可能是什么原因导致的了。同样,要从生产者,消费者和broker三端分别来说。

生产者端

对于生产者来说,如果他发送过程中失败了,那么消息肯定会丢。生产者失败的情况并不多,一般就是以下2种情况了:

未开启消息确认(常见)

  • acks=0:消息发送后不等待Kafka响应,网络失败或Kafka挂掉就会丢消息
  • acks=1:只等 leader broker 确认写入成功,follower 尚未同步时 leader 挂了也可能丢失

acks是啥,该如何配置,看上面的链接就够了,这里不重复说了

未处理发送失败的情况(常见)

我们通常使用的producer.send(msg)其实是一种异步发送,发送消息的时候,方法会立即返回,但是并不代表消息一定能发送成功。这时候如果失败了,是没办法感知的。

所以,如果你没用用callback的机制来处理失败的回调,也可能会导致消息丢失。

发送过程中,Producer挂了

这种情况也有可能出现,就是消息正准备发呢,但是没等发出去,应用就挂了。那么消息也可能会丢了

Broker端

下面这篇也重点介绍了Broker导致消息丢的情况,这里简单总结下。

✅为什么Kafka没办法100%保证消息不丢失?

Broker挂了(不常见)

最常见的就是Broker挂了的情况,还没来及做消息的持久化以及同步,他挂了,那么消息就可能会丢了。

那有人说,Broker不是个集群么?集群的话挂了不是有选举机制么。确实,那么如果是下面的情况一样会丢消息。

leader 还没同步给 follower,就挂了(不常见)

如果在 acks=1这种情况下,但 leader broker 在follower还没同步完成之前就挂了,那么数据就丢了。

未开启主从同步或者没有集群部署,leader挂了(不常见)

这种也是有可能的,就只有一个leader在抗,挂了就完蛋了。

消息一直不成功

Kafka的消息默认保存72小时,在消息过期前,消费者一直没有消费成功,到期后消息会被删除。这种情况也可能会导致消息丢失。

消费者端

到了消费者这,消息在丢失的情况就比较少了,但是也不是没有,比如。。。

没处理成功就自动提交了offset(常见)

不要以为没有这种情况,你比如说批量消费的情况,你设置了自动提交,那么就有可能把未成功消费的消息给丢掉。

✅Kafka的批量消费如何确保消息不丢?

扩展知识

防止消息丢失最佳实践

  • 生产者:
acks=-1 // 表示 Leader 和 Follower 都接收成功时确认;可以最大限度保证消息不丢失,但是吞吐量低。
retries=3 // 生产端的重试次数
retry.backoff.ms = 300  //消息发送超时或失败后,间隔的重试时间

使用**producer.send(msg, callback)**方法处理异常。

  • Broker :
min.insync.replicas=5 //表示 ISR 最少的副本数量,通常设置 min.insync.replicas >1,这样才有可用的follower副本执行替换,保证消息不丢失
unclean.leader.election.enable=false //是否可以把非 ISR 集合中的副本选举为 leader 副本。
replication.factor=5 //表示分区副本的个数,replication.factor >1 当leader 副本挂了,follower副本会被选举为leader继续提供服务。
  • 消费者:
enable.auto.commit=false

手动提交 offset,确保处理完成后再提交。