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跟踪记录偏移量,并将偏移量维护到数据库中,可作为唯一标识字段等。
部分代码
msgList =consumer.poll(Duration.ofMillis(100));
if (msgList !=null && !msgList.isEmpty()) {
for (ConsumerRecord record :msgList) {
currentOffsets.put(new TopicPartition(record.topic(), record.partition()), new OffsetAndMetadata(record.offset() +1));
4.在订阅数据时,重写ConsumerRebalandeListener再分区监听器,即继承ConsumerRebalanceListener接口,
#consumer.subscribe(TOPIC_LIST, new SaveOffsetOnRebalance(consumer));
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:
工作之余,记录自己平时的一些小毛病,以及问题排查和解决方案思路。记录自己的经验和不足之处,笔记中可能会有很多不足之处,欢迎各位留言指正讨论。