一、消息丢失和重复消费
生产者:
1、生产者丢失消息
(1)、丢失场景
配置文件里面,ack设置为0,也就是生产者发送之后,
不管分区副本(leader和follower)是否收到都不管了,
如果发送失败,就会消息丢失。
ack设置为1,也就是生产者发送之后,只要leader接收到了,就会返回成功,
follower没来及同步的时候leader挂掉,就会消息丢失。
(2)、解决办法:
设置ack=all / -1,保证leader和follower分区都收到之后,
再返回给生产者成功。
如果其中有一个步骤异常,都会触发kafka的重试机制。
2、生产者重复消费
(1)、重复消息场景:
生产发送的消息没有收到正确的broke响应,导致producer重试。
producer发出一条消息,broke落盘以后因为网络等种种原因
发送端得到一个发送失败的响应或者网络中断,然后producer收到
一个可恢复的Exception重试消息导致消息重复。
(2)、解决办法:
启动kafka的幂等性
enable.idempotence=true 同时要求 ack=all 且 retries>1。
幂等原理:
每个生产者producer都有一个唯一id,producer每发送一条数据,
都会带上一个sequence,当消息落盘,sequence就会递增1。
那么只需要判断当前消息的sequence是否大于当前最大sequence,
大于就代表此条数据没有落盘过,可以正常消费。
不大于就代表落盘过,这个时候重发的消息会被服务端拒掉从而避免消息重复。
broker:
1、broker丢失数据
(1)、丢失场景
<1>、ack=1,follower没来及同步的时候leader挂掉也不好重试,
当follower被选举为新的leader时,这部分没同步的数据就丢失了。
<2>、分区副本数小于2个,导致没有足够数量的副本参与新leader选举,
无法保证数据的高可用,当原leader挂了之后,
没有follower被选举为leader。
(2)、解决办法:
<1>、ack=-1,保证leader和follower分区的数据可以落盘。
<2>、保证分区副本数大于2,保证数据的高可用性
<3>、设置重试次数等。
消费者
1、消费者丢失消息
(1)、丢失场景
<1>、设置的自动提交offset,当消费者已经消费到了消息,
也记录了新的偏移量offset,但是后面的业务失败了或者
没来得及处理就挂了。
这时候因为offset已经更新了,这条消息也再消费不到了。
(2)、解决办法:
<1>、设置为手动提交成功,当业务代码都执行完成之后,
再进行手动提交,确保消息被真正处理到。
2、消费者消息重复
(1)、丢失场景
<1>、数据消费完没有及时提交offset到broke。
消息消费端在消费过程中挂掉没有及时提交offset到broke,
另一个消费端启动拿之前记录的offset开始消费,
由于offset的滞后性可能会导致新启动的客户端有少量重复消费。
(2)、解决办法
<1>、设置为手动提交成功
<2>、在下游程序里面做幂等,
幂等实际上就两种方法:
(1)、将唯一键存入第三方介质,
要操作数据的时候先判断第三方介质(数据库或者缓存)
有没有这个唯一键。
(2)、将版本号(offset)存入到数据里面,
然后再要操作数据的时候用这个版本号做乐观锁,
当版本号大于原先的才能操作。