Kafka丢数据、重复消费、顺序消费的问题
面试官:今天我想问下,你觉得Kafka会丢数据吗?
候选者:嗯,使用Kafka时,有可能会有以下场景会丢消息
候选者:比如说,我们用Producer发消息至Broker的时候,就有可能会丢消息
候选者:如果你不想丢消息,那在发送消息的时候,需要选择带有 callBack的api进行发送
候选者:其实就意味着,如果你发送成功了,会回调告诉你已经发送成功了。如果失败了,那收到回调之后自己在业务上做重试就好了。
候选者:等到把消息发送到Broker以后,也有可能丢消息
候选者:一般我们的线上环境都是集群环境下嘛,但可能你发送的消息后broker就挂了,这时挂掉的broker还没来得及把数据同步给别的broker,数据就自然就丢了
候选者:发送到Broker之后,也不能保证数据就一定不丢了,毕竟Broker会把数据存储到磁盘之前,走的是操作系统缓存
候选者:也就是异步刷盘这个过程还有可能导致数据会丢
面试官:嗯...
候选者:嗯,到这里其实我已经说了三个场景了,分别是:producer -> broker ,broker->broker之间同步,以及broker->磁盘
候选者:要解决上面所讲的问题也比较简单,这块也没什么好说的...
候选者:不想丢数据,那就使用带有callback的api,设置 acks、retries、factor等等些参数来保证Producer发送的消息不会丢就好啦。
面试官:嗯...
候选者:一般来说,还是client 消费 broker 丢消息的场景比较多
面试官:那你们在消费数据的时候是怎么保证数据的可靠性的呢?
候选者:首先,要想client端消费数据不能丢,肯定是不能使用autoCommit的,所以必须是手动提交的。
候选者:我们这边是这样实现的:
候选者:一、从Kafka拉取消息(一次批量拉取500条,这里主要看配置)时
候选者:二、为每条拉取的消息分配一个msgId(递增)
候选者:三、将msgId存入内存队列(sortSet)中
候选者:四、使用Map存储msgId与msg(有offset相关的信息)的映射关系
候选者:五、当业务处理完消息后,ack时,获取当前处理的消息msgId,然后从sortSet删除该msgId(此时代表已经处理过了)
候选者:六、接着与sortSet队列的首部第一个Id比较(其实就是最小的msgId),如果当前msgId<=sort Set第一个ID,则提交当前offset
候选者:七、系统即便挂了,在下次重启时就会从sortSet队首的消息开始拉取,实现至少处理一次语义
候选者:八、会有少量的消息重复,但只要下游做好幂等就OK了。
面试官:嗯,你也提到了幂等,你们这业务怎么实现幂等性的呢?
候选者:嗯,还是以处理订单消息为例好了。
候选者:幂等Key我们由订单编号+订单状态所组成(一笔订单的状态只会处理一次)
候选者:在处理之前,我们首先会去查Redis是否存在该Key,如果存在,则说明我们已经处理过了,直接丢掉
候选者:如果Redis没处理过,则继续往下处理,最终的逻辑是将处理过的数据插入到业务DB上,再到最后把幂等Key插入到Redis上
候选者:显然,单纯通过Redis是无法保证幂等的(:
候选者:所以,Redis其实只是一个「前置」处理,最终的幂等性是依赖数据库的唯一Key来保证的(唯一Key实际上也是订单编号+状态)
候选者:总的来说,就是通过Redis做前置处理,DB唯一索引做最终保证来实现幂等性的
面试官:ok,了解了。
面试官:你们那边遇到过顺序消费的问题吗?
候选者:嗯,也是有的,我举个例子
候选者:订单的状态比如有 支付、确认收货、完成等等,而订单下还有计费、退款的消息报
候选者:理论上来说,支付的消息报肯定要比退款消息报先到嘛,但程序处理的过程中可不一定的嘛
候选者:所以在这边也是有消费顺序的问题
候选者:但在广告场景下不是「强顺序」的,只要保证最终一致性就好了。
候选者:所以我们这边处理「乱序」消息的实现是这样的:
候选者:一、宽表:将每一个订单状态,单独分出一个或多个独立的字段。消息来时只更新对应的字段就好,消息只会存在短暂的状态不一致问题,但是状态最终是一致的
候选者:二、消息补偿机制:另一个进行消费相同topic的数据,消息落盘,延迟处理。将消息与DB进行对比,如果发现数据不一致,再重新发送消息至主进程处理
候选者:还有部分场景,可能我们只需要把相同userId/orderId发送到相同的partition(因为一个partition由一个Consumer消费),又能解决大部分消费顺序的问题了呢。
面试官:嗯...懂了

欢迎关注我的微信公众号【Java3y】来聊聊Java面试

【对线面试官-移动端】系列 一周两篇持续更新中!
【对线面试官-电脑端】系列 一周两篇持续更新中!
原创不易!!求三连!!
Kafka丢数据、重复消费、顺序消费的问题的更多相关文章
- RocketMQ事务消费和顺序消费详解
一.RocketMq有3中消息类型 1.普通消费 2. 顺序消费 3.事务消费 顺序消费场景 在网购的时候,我们需要下单,那么下单需要假如有三个顺序,第一.创建订单 ,第二:订单付款,第三:订单完成. ...
- 【转】RocketMQ事务消费和顺序消费详解
RocketMQ事务消费和顺序消费详解 转载说明:该文章纯转载,若有侵权或给原作者造成不便望告知,仅供学习参考. 一.RocketMq有3中消息类型 1.普通消费 2. 顺序消费 3.事务消费 顺序消 ...
- RocketMQ的顺序消费和事务消费
一.三种消费 :1.普通消费 2. 顺序消费 3.事务消费 1.1 顺序消费:在网购的时候,我们需要下单,那么下单需要假如有三个顺序,第一.创建订单 ,第二:订单付款,第三:订单完成.也就是这个三个 ...
- Kafka丢失数据问题优化总结
数据丢失是一件非常严重的事情事,针对数据丢失的问题我们需要有明确的思路来确定问题所在,针对这段时间的总结,我个人面对kafka 数据丢失问题的解决思路如下: 是否真正的存在数据丢失问题,比如有很多时候 ...
- kafka丢失和重复消费数据
Kafka作为当下流行的高并发消息中间件,大量用于数据采集,实时处理等场景,我们在享受他的高并发,高可靠时,还是不得不面对可能存在的问题,最常见的就是丢包,重发问题. 1.丢包问题:消息推送服务,每天 ...
- 实际业务处理 Kafka 消息丢失、重复消费和顺序消费的问题
关于 Kafka 消息丢失.重复消费和顺序消费的问题 消息丢失,消息重复消费,消息顺序消费等问题是我们使用 MQ 时不得不考虑的一个问题,下面我结合实际的业务来和你分享一下解决方案. 消息丢失问题 比 ...
- kafka 消费组功能验证以及消费者数据重复数据丢失问题说明 3
原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 背景 上一篇文章记录了kafka的副本机制和容错功能的说明,本篇则主要在上一篇文章的基础上 ...
- SparkStreaming消费kafka中数据的方式
有两种:Direct直连方式.Receiver方式 1.Receiver方式: 使用kafka高层次的consumer API来实现,receiver从kafka中获取的数据都保存在spark exc ...
- 【Java面试】Kafka 怎么避免重复消费
Hi,大家好,我是Mic 一个工作5年的粉丝找到我. 他说: "Mic老师,你要是能回答出这个问题,我就佩服你" 我当场就懵了,现在打赌都这么随意了吗? 我问他问题是什么,他说&q ...
随机推荐
- LevelDB学习笔记 (3): 长文解析memtable、跳表和内存池Arena
LevelDB学习笔记 (3): 长文解析memtable.跳表和内存池Arena 1. MemTable的基本信息 我们前面说过leveldb的所有数据都会先写入memtable中,在leveldb ...
- 源码解析Java Attach处理流程
前言 当Java程序运行时出现CPU负载高.内存占用大等异常情况时,通常需要使用JDK自带的工具jstack.jmap查看JVM的运行时数据,并进行分析. 什么是Java Attach 那么JVM自带 ...
- [刘阳Java]_CSS鼠标悬停
小白在学习前端技术时候,一定会在刚开始的时候学习CSS2和CSS3的相关知识.这篇内容给大家介绍一个CSS鼠标悬停的效果.大家可以先看下面的效果图,然后我们在说一下实现的效果要求吧 上图效果非常简单和 ...
- [刘阳Java]_Java基础面试中的常识问题
1. anonymous inner class(匿名内部类)是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)? 不行,对于匿名内部类,看到的一句话 ...
- 【论文阅读】Socially aware motion planning with deep reinforcement learning-annotated
目录 摘要部分: I. Introduction 介绍 II. Background 背景 A. Collision Avoidance with DRL B. Characterization of ...
- 【LeetCode】242. 有效的字母异位词
242. 有效的字母异位词 知识点:字符串:哈希表 题目描述 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词. 注意:若 s 和 t 中每个字符出现的次数都相同,则称 ...
- Appium - adb命令操作
1.Android 调试桥adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信.它可为各种设备操作提供便利,如安装和调 ...
- 03 高性能IO模型:采用多路复用机制的“单线程”Redis
本篇重点 三个问题: "Redis真的只有单线程吗?""为什么用单线程?""单线程为什么这么快?" "Redis真的只有单线程吗? ...
- Django orm 常用查询筛选总结
本文主要列举一下django orm中的常用查询的筛选方法: 大于.大于等于 小于.小于等于 in like is null / is not null 不等于/不包含于 其他模糊查询 model: ...
- 【NLP学习其四】如何构建自己用于训练的数据集?什么是词性标注?
数据集与词性标注 数据集是NLP中的重要一环. 但是提到数据集,很多人的第一个想法可能是:"这玩意从网上下载就好了,不用管". 真的不用管?最开始我也是这么认为的 于是我直奔CoN ...