一、生产者消息丢失

如果配置ack=-1,那么要求leader和ISR中的副本都有ack那么才会确保发送成功,在网络抖动或者网络故障的情况下,生产者和消息队列服务器无法通信了,生产者就会认为这个消息丢失了,通常情况下会采用消息重新发送的机制。这个也会造成消息重复。

KafkaProducer 一般会发生两种类型的异常 可重试的异常和不可重试的异常 。常见的可重试异常有
NetworkException
LeaderNotAvailableException
UnknownTopicOrPartitionException
NotEnoughReplicasException
NotCoordinatorException
比如 NetworkException 表示网络异常,这个有可能是由于网络瞬时故障而导致的异常,可以通过重试解决.

二、消息队列服务器消息丢失

kafka之所以这么快是采用了

  • 磁盘顺序写入
  • 大量采用页缓存
  • 零拷贝

页缓存:消息如何内存后,不是立马就刷盘的,而是累计的一定数量才刷盘的,这个有个参数可以控制。如果还没有还没有刷盘,然后机器宕机,这个时候也有可能造成消息丢失。但是kafka一般都会采用集群机制,这种让ISR中的所有机器集体宕机的概率太小.
我之前的一篇博客 ISR机制

三、消费端消息丢失

最常见的情况是取到消息后,消息处理失败,但是还是进行了offset的更新。
你需要保证一定要等到消息接收和处理完成后才能更新消费进度,当然这样可能引起消息重复的问题。比方说某一条消息在处理之后,消费者恰好宕机了,那么因为没有更新消费进度,所以当这个消费者重启之后,还会重复地消费这条消息。

四、生产者的消息重复

在消息生产过程中,在 Kafka0.11 版本和 Pulsar 中都支持“producer idempotency”的特性。低版本的还是建议在消费者段进行消息去重

五、消费者的消息重复

如果消息接收成功,然后处理经过步骤1 和步骤2 然后进行offset的更新,首先步骤1成功了,步骤2失败了,然后offset就没有就行更新,这样 下次取消息后还是这条消息,然后步骤1又会重复执行一遍。

最常见的做法是建立去重表,在进行步骤1的时候就进行判断。但是这个时候就要保证步骤1 和步骤2 和 向去重表中插入数据在同一个事物中。

最严格的做法就是 接受消息的方法具有幂等性。