Kafka作为一款高性能、分布式的消息队列系统,在大数据领域被广泛应用。然而,在使用Kafka时,重复消费问题是一个常见的挑战,可能会对系统的数据一致性和业务逻辑造成影响。我知道Kafka这个名词时还是在2019年刚工作的时候,但那时候公司使用的消息队列体量很小,所以只用了activeMq,我没再继续深入研究kafka相关;2021年下半年时,去了新公司,新公司规模大,数量量也巨大,许多系统之间要进行数据传输,我们用的消息中间件就是Kafka,于是拜读了一些Kafka介绍,看了一两个视频,看了下前辈们在代码中怎么使用的Kafka,装模做样的用起来了,也倒也没有发生什么问题,23年3月份某天晚上,我们上线了一个呕心沥血做了半年的项目,那个项目从服务构建、数据库设计、核心功能开发、与上下游系统的沟通交互我都深深的参与其中,结果上线当晚倒也没啥,第二天下午时,我们的下游系统同事打来电话了,问我们系统被攻击了么,怎么有个叫“田由甲”的用户信息一直在抛送呢。此刻问题丢我这了,毕竟和下游系统交互这块一直是我负责的,我立马打开了服务日志,却发现从凌晨3点到下午之间的日志一直被田由甲霸屏了,整个日志消息都是“用户田由甲修改了个人信息,value:{......},partition:{......},offset=XXXXX”。

我知道,现在这个问题丢给如今的我来看肯定很快能解决掉的,但对于当时的我来讲确实有一点懵,因为确实没遇到过Kafka重复消费的问题,我看遍日志也没发现打印异常的地方,而且每次修改完信息后,数据也同步给下游系统了,这个功能上线前测了无数次,怎么一上线偏偏一直在这打印数据呢。当时的脑子闪过一个念头,该不会我们的用户系统真的被攻击了,有人在定时刷我们的接口,一直修改这个田由甲的数据吧。当时的我们立刻找个田大哥的手机号,打过去询问了下,结果田大哥告诉我们他确实凌晨登了一次系统,只不过就修改了下昵称,之后没再登过了。看来还得回到问题本身,想想为什么测试环境没有重复消费,而生产一直消费个没完了呢。在分析问题之前,先给大家简单介绍下我们的数据流向:

我们的系统很大,里面有几十个微服务,有一个用户中心,它对应的是一个单独的用户服务,所有全量的用户数据在这里都能找的到,每个业务服务呢都是处理不同的业务场景的,服务自己面对的客户群体也不一样,可以说每个业务服务这里也需要用到一份属于自己客户群体的客户数据,在自己的数据库中留存以方便逻辑处理和使用,每当用户在用户中心增加修改删除时,用户服务会把数据丢到一个公共的topic中,我们权且叫做topicA,三个业务服务去订阅这个topicA,根据type的不同选择来消费数据进行落库更新处理,我新上线的这个叫做服务三吧,它和下游系统的APP有数据上的交互,我从用户系统接到数据变化后,进行落库,然后数据业务加工后会推送到topicB中,下游系统订阅了这个topicB,接收到数据再更新自己的用户信息。

  问题回到田由甲身上,首先用户说只修改了一次,而且我们公司有自己的安全部门,被这样攻击近10个小时不太现实,而且业务系统一监听田由甲也没发生问题,那问题肯定不在用户服务的数据跑送上,必然是我们新上线的服务出现了问题。我静下心来仔细观察了下日志,发现日志上的offset都是同一个值,说明程序执行完之后,偏移量没有被正确的提交,导致一直在消费同一条数据,但是另一个问题来了,既然下游APP接到了数据,说明方法逻辑肯定都走完了,排除发生异常的可能,那为何偏移量还是提交不上呢,于是又排查了下我写的Kafka消费和别人写的区别,我发现新服务的Kafka配置我开启了自动提交,而老服务别人是使用的手动提交方法,突然有了想法,手动提交是逻辑执行完之后执行ack.acknowledeg(),而自动提交则和配置的提交时间有关,如果方法执行超过了配置的时间阈值,那么偏移量将提交不上去。想到这,抓紧先把偏移量自动提交修改为了手动提交,将代码重新部署下。

  其实这里还有个问题没有根本解决,为什么配置自动提交测试环境一直没有出现重复消费的问题呢,那段处理逻辑代码并不复杂,怎么会执行时间超出阈值设置的几十秒呢?我仔细想了下,一般代码慢都会和数据库交互有关,大多情况发生在查询上,而我写的这段逻辑只有一个地方通过手机号查用户信息和DB进行查询方面的交互了,想到这,我立马意识到一个问题,这张表并不是我新建的,我只是在这张用户表加了几个字段以便于我新业务新服务的使用,这个表生产一直有,所以说它和测试环境最大区别那就是数据量,虽然我参与的这部分用户群体只是整个系统总的用户群体的一个子集,只占很小的一部分,那在生产环境上,也肯定是有几十万条数据的,突然有个大胆的想法,该不会这张user表前辈们没有加索引吧!我立马登上生产库查看,好家伙,这张用户表,果然一个索引都没建,一个mysql表,几十万条数据,没有索引,直接用手机号查,那肯定是全表扫描,不慢才怪。。。测试环境没有那么大的数据量,必然测不出来啊,于是立马给用户表的手机号字段建了索引。

  当时的我由于对Kafka重复消费问题第一次遇到,确实解决它废了点心思,最近这一年里,参与的项目几乎都使用到了Kafka,又遇到了好多次Kafka消费慢等优化的需求,愈加熟练的去解决了,接下来我将言归正传,官方的陈述下Kafka重复消费问题的根本原因、常见场景以及解决方法,希望能够帮助读者更好地理解和应对这一问题。

1. 重复消费问题的根本原因

Kafka的消费者组模型是保证高吞吐量和水平扩展性的关键,但也为重复消费问题埋下了隐患。消费者组中的每个消费者会负责消费特定分区的消息,并维护自身的消费偏移量(offset),用于记录已经消费的消息位置。然而,如果消费者在处理消息时发生故障或者处理时间过长,可能会导致消费偏移量未能及时提交,从而造成消息被重复消费的情况。

此外,Kafka本身并不保证消息的顺序性,如果消息在生产者端重试发送或者在网络传输过程中发生重复,也会导致消息被重复消费的情况发生。因此,要解决重复消费问题,需要从多个方面进行考虑和处理。

2. 常见场景下的重复消费问题

2.1. 消费者故障重启

当消费者由于故障而重启时,可能会导致消费偏移量丢失或者未能及时提交,从而造成消息被重复消费。

2.2. 消费者处理时间过长

如果消费者处理消息的时间过长,可能会导致在消息处理完成前发生故障或重启,从而引发重复消费问题。

2.3. 消息重试或网络传输问题

在消息生产和传输过程中,如果消息发生重试发送或者在网络传输过程中发生重复,也会导致消息被重复消费的情况发生。

3. 解决方法

3.1. 使用幂等性处理

在消费者端实现幂等性处理是解决重复消费问题的有效方法。通过在消费端记录已经处理过的消息ID或者通过消息去重的方式,可以保证同一消息不会被重复处理。

3.2. 提交消费偏移量

及时提交消费偏移量是避免重复消费的关键。可以通过设置适当的提交频率或者在消息处理完成后手动提交偏移量来确保消费偏移量的准确性。

3.3. 使用Exactly-Once语义

Kafka提供了Exactly-Once语义来解决重复消费和消息丢失的问题,可以通过配置事务或者幂等性生产者来实现Exactly-Once语义。

4. 结语

在使用Kafka时,重复消费问题是一个需要重视的挑战,但通过合理的设计和实施解决方案,可以有效地避免和解决重复消费带来的影响。希望本文的内容能够帮助读者更好地理解Kafka重复消费问题并采取相应的措施,确保系统的数据一致性和稳定性。

5. 参考资料

  1. Kafka官方文档: https://kafka.apache.org/documentation/
  2. Confluent官方文档: https://docs.confluent.io/

“田由甲” - Kafka重复消费线上问题暴雷的更多相关文章

  1. Kafka重复消费和丢失数据研究

    Kafka重复消费原因 底层根本原因:已经消费了数据,但是offset没提交. 原因1:强行kill线程,导致消费后的数据,offset没有提交. 原因2:设置offset为自动提交,关闭kafka时 ...

  2. 记一次 Kafka 集群线上扩容

    前段时间收到某个 Kafka 集群的生产客户端反馈发送消息耗时很高,于是花了一段时间去排查这个问题,最后该集群进行扩容,由于某些主题的当前数据量实在太大,在对这些主题迁移过程中话费了很长一段时间,不过 ...

  3. elk 使用中遇到的问题(kafka 重复消费)

    问题描述: 在使用过程中,当遇到大量报错的时候,我们到eagle后台看到报错的那个consumer的消费情况到到lag 远远大于0(正常情况应该为0),activie  节点没有,kibana面板上没 ...

  4. storm调用kafka重复消费的问题

    1. 实现IBolt接口的bolt需要显式调用collector.ack(); 2. 继承自BaseBasicBlot的bolt, 会帮你自动调用ack的

  5. BitArray虽好,但请不要滥用,又一次线上内存暴增排查

    一:背景 1. 讲故事 前天写了一篇大内存排查在园子里挺火,这是做自媒体最开心的事拉,干脆再来一篇满足大家胃口,上个月我写了一篇博客提到过使用bitmap对原来的List<CustomerID& ...

  6. kafka重复数据问题排查记录

    问题 向kafka写数据,然后读kafka数据,生产的数据量和消费的数据量对不上. 开始怀疑人生,以前奠定的基础受到挑战... 原来的测试为什么没有覆盖生产量和消费量的对比? 消费者写的有问题?反复检 ...

  7. kafka一直rebalance故障,重复消费

    今天我司线上kafka消息代理出现错误日志,异常rebalance,而且平均间隔2到3分钟就会rebalance一次,分析日志发现比较严重.错误日志如下 08-09 11:01:11 131 pool ...

  8. 记一次线上Kafka消息堆积踩坑总结

    2018年05月31日 13:26:59 xiaoguozi0218 阅读数:2018更多 个人分类: 大数据   年后上线的系统,与其他业务系统的通信方式采用了第三代消息系统中间件Kafka.由于是 ...

  9. Kafka丢数据、重复消费、顺序消费的问题

    面试官:今天我想问下,你觉得Kafka会丢数据吗? 候选者:嗯,使用Kafka时,有可能会有以下场景会丢消息 候选者:比如说,我们用Producer发消息至Broker的时候,就有可能会丢消息 候选者 ...

  10. 【Java面试】Kafka 怎么避免重复消费

    Hi,大家好,我是Mic 一个工作5年的粉丝找到我. 他说: "Mic老师,你要是能回答出这个问题,我就佩服你" 我当场就懵了,现在打赌都这么随意了吗? 我问他问题是什么,他说&q ...

随机推荐

  1. 将input 中的小写字母转化为大写字母

    小写转换为大写,使用toLocaleUpperCase() options.element.find(".CarNumber").textbox({ label: '车牌号:', ...

  2. 从嘉手札<2023-11-20>

    写给十年如一日的偶像--Faker "我看了一下,觉得视频还不够清晰,等我换一个清晰点的摄像头再回来直播,不要走开~" 繁星满天,流光飞逝. 世界是一场盛大的表演, 舞台上熙熙攘攘 ...

  3. TP5发送短信限制

    <?php //发送手机验证码 function smsCode() { //dump($this->request->post()); //请求方式验证 /*if (!$this- ...

  4. 零基础入门学习JAVA课堂笔记 ——DAY08

    异常 1.什么是异常? Exception 异常是指程序在运行过程中出现的不期而至的各种状况 异常发生在程序运行期间,它影响了正常程序执行流程 通俗易懂的表达就是,程序在发生意料之外或者拿到的不是想要 ...

  5. Linux-Shell 小数运算,四舍五入

    在shell中做小数运算,可以借助bc 或者awk工具 一.使用bc做小数运算,scale指定小数点位数 1.加法运算(scale参数无效) #echo "5.999 + 5.001&quo ...

  6. 快速上手typescript(基础篇)

    壹 ❀ 引 在javascript开发中,你可能也遇到过我这样的苦恼,在维护某段几年前的老旧代码时,我发现了某个数据加工方法fn,而且根据现有逻辑来看fn的某个参数是一个数组,因为新需求我需要对数组做 ...

  7. JS Leetcode 74. 搜索二维矩阵题解分析,二分法与坐标轴法

    壹 ❀ 引 本题来自Leetcode74. 搜索二维矩阵,虽然难度是中等,但如果站在做出来的角度,你会发现其实并不难,题目描述如下: 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值. ...

  8. Centos8 单机配置 Zookeeper3.6.3 集群

    安装 Zookeeper 3.6.3 前提 已经安装好 JDK8+. 如果使用JDK8, 版本需要在211以上. 下载, 解压 使用root用户 wget https://downloads.apac ...

  9. Swoole从入门到入土(19)——WebSocket服务器[文件传输]

    要利用WebSocket进行文件传输,我们需要讨论两种情况,分别是:发送方可以是客户端,和 发送方是服务端. 1.发送方是客户端  1)服务端接收 $server->on('message', ...

  10. 新零售SaaS架构:订单履约系统的应用架构梳理

    订单履约系统的核心能力 通过分析订单履约的全流程和各个业务活动,我们可以梳理出订单履约的核心业务链路,基于业务链路,我们抽象出订单履约系统的三大系统能力,分别为履约服务表达.履约调度.物流配送. 履约 ...