kafka之浅谈如何去保证数据不重复消费

kafka之浅谈如何去保证数据不重复消费

一。背景:上游数据流,将数据推入kafka中,作为消费者,消费数据并进行处理,对于交易数据,非常敏感,不能出现重复,在消费这一过程中,如何去保证我们不会去重复消费数据。

二。导致数据重复消费的原因一般有:
1.数据消费处理成功(落地入库,或者各种处理成功),向kafka中提交偏移量时,由于宕机,或者断网之类的失败了,这时候其实相对与系统来说,这笔数据已经是处理过了,就会出现重复数据。
2.一般是有新的消费者加入之类的,发生了再均衡,导致数据重发消费。
三。项目使用真实使用
方案:
1.关闭自动提交,设置enable-auto-commit为 false,采用手动Offset提交
2.提交方式,简单提一下两种提交方式的却别
consumer.commitAsync();//异步提交
异步提交:异步提交,非阻塞,有更好的并发性能,但是同时也是还会提交失败,导致数据重复。
consumer.commitSync();//同步提交
同步提交:同步提交,是阻塞的,在提交失败时,会一直阻塞,直到超时,可回调。

这里我们采用异步+同步提交,异步提交失败后,采用同步提交,一直阻塞,达到超时时间还未提交,执行同步提交回调,可记录提交失败的数据
简单示例:
public void commitOffset() {
try {
consumer.commitAsync();//异步提交
} catch (CommitFailedException e) {
consumer.commitSync();
}
}
3.每次使用map跟踪记录偏移量,并将偏移量维护到数据库中,可作为唯一标识字段等。
在这里插入图片描述

4.在订阅数据时,重写ConsumerRebalandeListener再分区监听器,即继承ConsumerRebalanceListener接口,
在这里插入图片描述
5.当发生再均衡前后也要记录提交偏移量,根据具体的使用场景,也可以选着将offset维护在库里面,比如,在对消费的数据进行落地时这一场景,有可能会出现入库成功,提交失败,或者提交成功,入库失败等,这一类场景最安全的就是落地维护offset,但是也确实带来了一定的复杂度,对库的读写性能要求也比较高,redis就比较合适,这里不深挖了。
重写方法:onPartitionsRevoked,该方法会在再均衡开始之前和消费者停止读取消息之后被调用。在这个方法里,我们需要做的是,把map中跟踪的偏移量进行提交。
简单例子:
public void onPartitionsRevoked(Collection collection) {
consumer.commitSync();
if(logger.isInfoEnabled()){
logger.info("*- in ralance:onPartitionsRevoked");
}
}
重写方法:onPartitionsAssigned,该方法会在重新分配partition之后和消费者开始读取消息之前被调用。这里我们需要做的是,读取我们库中维护的offset,并使用seek设置开始offset位置。
@Override
public void onPartitionsAssigned(Collection collection) {
//rebalance之后 获取新的分区,获取最新的偏移量,设置拉取分量
for (TopicPartition partition : collection) {

        if(logger.isInfoEnabled()){
            logger.info("*- partition:" + partition.partition());
        }
        //获取消费偏移量,实现原理是向协调者发送获取请求

        OffsetAndMetadata offset = consumer.committed(partition);
        //设置本地拉取分量,下次拉取消息以这个偏移量为准

        consumer.seek(partition,getOffsetFromDB(partition));
    }

这里主要体现思路,具体的方案,一切从实际业务出发,不然就是耍流氓,但是大多思路不变,变动的是细节

热爱生活的码小子wmxiang:
工作之余,记录自己平时的一些小毛病,以及问题排查和解决方案思路。记录自己的经验和不足之处,笔记中可能会有很多不足之处,欢迎各位留言指正讨论。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值