acks=-1的情况下是说所有副本都同步完成后,才确认发送成功。假如某一时刻,只有leader写入成功,follower 还没写入成功,发生异常(可能是leader挂了,也可能是网络异常),导致了重试机制的发生,那此时会不会导致消息重复发送了?为什么,各位大佬帮忙解释一下
为了保证消息不丢失,会重复的。
其实很简单,服务端是个黑盒,你发送过去了报错了,因为你有重试机制,客户端就一定会重发。
服务端会有2种情况
1、保存成功了(超过1个节点)
2、保存失败了(一定是全失败)
如果服务端明确的告诉你失败了,这个时候其实还不会有重复的消息,leader切换了,fllower成为了leader,fllower没有,那你重发也不会重复。
但凡你保存超过1个副本保存成功,并且没有down,这个follower成为leader,那消息也不会丢,你再发也会重复。
最麻烦的是超时,这种情况,它也不告诉你结果,你根本不知道成功还是失败,不发就丢,发了就有可能重复。
感谢大佬解答,分析特别全面,明白了
min.insync.replicas: 当Producer设置acks为-1时,指定需要写入成功的副本的最小数目。min.insync.replicas=1确保当leader写入成功后就可以确认发送成功,不会重复发送。
min.insync.replicas 没有设置或者2(发生异常),原leader 还是当选leader,数据应该是会重复发送;原leader变成follower时,数据丢失。
感谢大佬解答,和半兽人说的应该是一个意思,但是缺少前提条件,容易搞混。
重复消费还是存在的,就看你采取什么样的措施了,重复数据可以采取发送布隆姆过滤器进行去重或者发送到redis里面进行去重。
大佬在实际项目中是如何做消费去重的呢?有做过吗?
你的答案