普通人:Kafka怎么避免重复消费?和高手的回答

你好,我叫麦克

一位工作了 5 年的粉丝找到了我。

他说:“麦克先生,如果你能回答这个问题,我会佩服你的”

当场惊呆了,现在下注这么随便吗?

我问他是什么问题,他说“卡夫卡如何避免双重消费的问题!”

看看下面的普通人和专家的答案!

普通人:

Kafka 避免重复消费的方式是,我们可以在该消息消费结束时使用类似于分布式锁的设计。

消费消息的时候,可以直接在redis中使用setNx等指令,然后将消息保存到redis中,然后如果重复发送,那么只需要判断redis中有消息即可最好不要存在。

大师:

好,我从几个方面来回答这个问题。

首先,存储在 Kafka Broker 上的消息有一个 Offset 标记。

然后kafka消费者通过offSet标签​​维护当前消费的数据,

每消费一批数据,Kafka Broker都会更新OffSet的值,避免重复消费。

默认情况下,消息被消费后,会自动提交Offset的值,避免重复消费。

Kafka消费者的自动提交逻辑默认间隔为5秒,即5秒后从Broker拉取下一条消息时提交。

所以在Consumer消费过程中,应用被强行杀死或关闭,可能会导致Offset无法提交,导致重复提交的问题。

另外,还有一种情况就是出现双耗的情况。

Kafka中有一个Partition Balance机制,就是将多个Partition均衡分配给多个消费者。

Consumer 将消费来自分配的 Partition 的消息。如果 Consumer 在默认的 5 分钟内无法处理这批消息。

会触发Kafka的rebalance机制,导致Offset无法自动提交。

再平衡后Consumer还是会从之前没有提交的Offset位置开始消费,这也会导致消息重复消费的问题。

基于这样的背景,我认为解决消息重复消费问题的方法有几种。

提高消费者端的处理性能,避免触发Balance。例如,可以异步处理消息,以缩短单条消息消费的市场。或者您可以调整消息处理的超时时间。它还可以减少一次从 Broker 拉取的数据条数。您可以为消息生成 md5 并将其保存在 mysql 或 redis 中。在处理消息之前,先去mysql或者redis判断是否已经被消费。这个方案其实使用了幂等性的思想。

© 版权声明
THE END
喜欢就支持一下吧
点赞93赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容