一碰就头疼的 Kafka 消息重复问题,立马解决!

一、前言

数据重复这个问题其实也是挺正常,全链路都有可能会导致数据重复。

通常,消息消费时候都会设置一定重试次数来避免网络波动造成的影响,同时带来副作用是可能出现消息重复。

整理下消息重复的几个场景:

  1. 生产端: 遇到异常,基本解决措施都是 重试 。

  • 场景一:leader分区不可用了,抛 LeaderNotAvailableException 异常,等待选出新 leader 分区。

  • 场景二:Controller 所在 Broker 挂了,抛 NotControllerException 异常,等待 Controller 重新选举。

  • 场景三:网络异常、断网、网络分区、丢包等,抛 NetworkException 异常,等待网络恢复。

  1. 消费端: poll 一批数据,处理完毕还没提交 offset ,机子宕机重启了,又会 poll 上批数据,再度消费就造成了消息重复。

怎么解决?

先来了解下消息的三种投递语义:

  • 最多一次( at most once): 消息只发一次,消息可能会丢失,但绝不会被重复发送。例如:mqtt 中 QoS = 0

  • 至少一次( at least once): 消息至少发一次,消息不会丢失,但有可能被重复发送。例如:mqtt 中 QoS = 1

  • 精确一次( exactly once): 消息精确发一次,消息不会丢失,也不会被重复发送。例如:mqtt 中 QoS = 2

了解了这三种语义,再来看如何解决消息重复,即如何实现精准一次,可分为三种方法:

  1. Kafka 幂等性 Producer 保证生产端发送消息幂等。局限性,是只能保证单分区且单会话(重启后就算新会话)

  2. Kafka 事务: 保证生产端发送消息幂等。解决幂等 Producer 的局限性。

  3. 消费端幂等:保证消费端接收消息幂等。蔸底方案。

1)Kafka 幂等性 Producer

幂等性指 :无论执行多少次同样的运算,结果都是相同的。即一条命令,任意多次执行所产生的影响均与一次执行的影响相同。

幂等性使用示例:在生产端添加对应配置即可

Properties props = new Properties();
props.put("enable.idempotence", ture); // 1. 设置幂等
props.put("acks", "all"); // 2. 当 enable.idempotence 为 true,这里默认为 all
props.put("max.in.flight.requests.per.connection", 5); // 3. 注意
  1. 设置幂等,启动幂等。

  2. 配置 acks,注意:一定要设置 acks=all,否则会抛异常。

  3. 配置 max.in.fl

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值