kafka怎么保证不重复消费
2023-01-11阅读(201)
问:kafka重复消费的原因
- 答:如果自动提交的偏移量小于客户端处理的最后一个消息的偏移量,那么处于两个偏移量之间的消息就会被重复处理,
假设我们采用了自动提交,且提交时间间隔为5s,在最近一次提交之后的3s发生了再均衡,再均衡之后,消费者从最后一次提交的偏移量位置开始读取消息。这个时候偏移量已经落后了3s,所以在这3s内到达的消息会被重复处理。可以通过修改提交时间间隔来更频繁地提交偏移量,减小可能出现重复悄息的时间窗,不过这种情况是无也完全避免的。
问:一条消息怎么被两个消费者消费
- 答:在保证MQ消息不重复的情况下,消费者消费消息成功后,在给MQ发送消息确认的时候出现了网络异常(或者是服务中断),MQ没有接收到确认,此时MQ不会将发送的消息删除,为了保证消息被消费,当消费者网络稳定后,MQ就会继续给消费者投递之前的消息。这时候消费者就接收到了两条一样的消息
- 答:如何保证消息不被重复消费,或者说如何保证消息幂等性。
rbbitmq,rocketmq,kafka,都有可能出现消息重复消费的情况,以kafka来说
kafka实际上有个offset的概念,就是每个消息写进去,都有一个offset,代表的消息的序号,然后consumer消费了数据之后,每隔一段时间(定期定时),会把自己消费过的offset提交一下,表示“我已经消费过了,下次重启之后,还是从上次消费到的offset来继续消费。
如果遇到意外情况,还没来得及提交offset,进程就被杀掉了,重启之后,可能有些消息要重复消费一次。
问:Kafka重复消费数据
- 答:从消息发送和消息消费两个方面去说。
「 ACK 」
0:producer不等待broker的ack,这一操作提供了一个最低的延迟,broker一接收到还没有写入磁盘就已经返回,当broker故障时有可能丢失数据。
1:producer等待broker的ack,partition的leader落盘成功后返回ack,如果在follower同步成功之前leader故障,那么将会丢失数据。
-1:producer等待broker的ack,partition的leader和follower全部落盘成功后才返回ack。但是如果在follower同步完成后,broker发送ack之前,leader发生故障,那么会造成数据重复。
「消费」
写入sink没有提交offset,下次消费还从处理过的offset消费。这个时候要么做到幂等不影响下游。要么就是事务+两阶段提交。
在消费者处理数据慢的时候(消费能力低),消费者会重复消费某个局部数据。在消费能力不变的情况下,陷入死循环。只有在消费能力增强后,才会跳出这个重复消费的死循环。
原理解析:
上图就是完整的kafka消费的过程,在consumer里面配置了一个超时时间。如果步骤2处理消息超时,那么consumer进行第3步会失败。这时候再次进入步骤1拉取重复的数据,如此往复。