面试官问:Kafka 会不会丢消息?怎么处理的?

news/2024/9/28 7:20:48
作者:Java3y
链接:https://www.zhihu.com/question/628325953/answer/3281764326
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

面试官:今天我想问下,你觉得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相关的信息)的映射关系,通过msgId用来获取相关元信息

候选者:五、当业务处理完消息后,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唯一索引做最终保证来实现幂等性的

 

 

面试官你们那边遇到过顺序消费的问题吗?

候选者:嗯,也是有的,我举个例子

候选者:订单的状态比如有 支付、确认收货、完成等等,而订单下还有计费、退款的消息报

候选者:理论上来说,支付的消息报肯定要比退款消息报先到嘛,但程序处理的过程中可不一定的嘛

候选者:所以在这边也是有消费顺序的问题

候选者:但在广告场景下不是「强顺序」的,只要保证最终一致性就好了。

候选者:所以我们这边处理「乱序」消息的实现是这样的:

候选者:一、宽表:将每一个订单状态,单独分出一个或多个独立的字段。消息来时只更新对应的字段就好,消息只会存在短暂的状态不一致问题,但是状态最终是一致的

候选者:二、消息补偿机制:另一个进行消费相同topic的数据,消息落盘,延迟处理。将消息与DB进行对比,如果发现数据不一致,再重新发送消息至主进程处理

候选者:还有部分场景,可能我们只需要把相同userId/orderId发送到相同的partition(因为一个partition由一个Consumer消费),又能解决大部分消费顺序的问题了呢。

 

 

面试官:嗯…懂了

Java开源项目推荐

我推荐一个拥有从零开始的文档的Java开源项目,既能用于毕业设计,又可以用在面试。已经有不少的同学通过这个项目拿到了大厂的offer啦(美团/vivo/阿里等等)

该项目业务极容易理解,代码结构是比较清晰的,最可怕的是几乎每个方法和每个类都带有中文注释,并且代码完全通过阿里开发插件检查。

拥有非常全的文档,作者从零搭建的过程都有详细地记录,项目里使用了蛮多的可靠和稳定的中间件的。在使用每一个技术栈之前作者都讲述了为什么要使用,以及它的业务背景。我看过,他所说的场景是完全贴合线上环境的

我感觉这个项目就是奔着真实互联网线上项目去设计和实现的,将项目克隆下来把中间件换成目前公司在用的,配合自身的需求完善下基础建设,它就能在线上运行了。

我跟着README文档的部署使用姿势很快就能跑起来,最少只需要依赖MySQL和Redis。作者还搞了个前端功能界面,这就让系统变得更好理解了。而且,在GitHub或者Gitee所提的Issue几乎都会有回复,看出来也非常乐于合并开发者们的pull request,会让人参与感贼强

我相信在校、工作一年左右或常年做内网CRUD后台的同学去看看肯定会有所启发,作者也会经常在群里回答该项目相关的问题和代码设计思路。

项目里会应用到各种设计模式(我稍微看了下,应该有7~8种吧),用到了各种的好用的工具组件,动态线程池、日志切面组件之类,都是主流的技术栈...目前这个项目GitHub和Gitee加起来已经 9K stars了,我相信破万是迟早的事情。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/45768.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

kafka 如何保证不重复消费又不丢失数据?

作者:Java3y链接:https://www.zhihu.com/question/483747691/answer/2392949203来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。面试官:今天我想问下,你觉得Kafka会丢数据吗? 候选者:嗯,使用Kafka时,有可能会有以下场景会丢消息 候选…

Angular 兄弟组件之间的传值

Angular 兄弟组件之间的传值 在Angular中,兄弟组件之间直接传递数据并不直接支持,但可以通过以下几种方式实现通信:1 使用服务(Service):创建一个服务,用于存储和管理需要共享的数据。在这个服务中定义一个BehaviorSubject或ReplaySubject(来自rxjs库),这些是可观察的对…

远光全栈AIGC数字创新平台入选“大模型行业应用十大典范案例”

6月4日至7日,由数字产业创新研究中心主办的2024中国数字企业峰会举行,远光软件自主研发的《全栈AIGC数字创新平台 YG-JT GPT》凭借其卓越的 AIGC技术创新实力与创新推广应用,成功入选“大模型行业应用十大典范案例”榜单。 本届峰会以“AI+ 数据x 向未来”为主题,聚焦AI+融…

《UML基础、案例与应用》习题记录-第20章

部分习题,使用visio或plantuml,非正确答案,仅供参考,欢迎评论,谢绝转载。 第20章 交互 20.6.2习题 1.略 2.3. 4. 5. 欢迎大家评论交流,发现博文中存在的问题一定要留言哦

远光九天平台荣获2024广东软件风云榜行业应用解决方案TOP10

6月13日,远光九天智能一体化云平台(简称:远光九天平台)在2024年粤港澳软件产业高质量发展大会、第十二届粤港云计算大会暨第七届粤港澳ICT大会,被授予2024广东软件风云榜“行业应用解决方案TOP10”奖项。 作为远光软件自主研发的全栈国产化技术底座,远光九天平台是采用云…

记录一下麒麟3.0内网安装python通过jdbc连接达梦6数据库

python通过jdbc连接达梦6麒麟3.0基于Red Hat 4.1.2-42,此版本可以编译python3.8.3,但是内网无法安装libffi-dev,导致无法安装JPype1和JayDeBeApi,所以改用python2.7.18 1、安装python2.7.18 https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz# 解压 tar -zxvf P…

生成SSL证书

生成SSL证书SSL 是一种加密协议,用于在网络通信中提供数据的保密性和完整性。它使用公钥和私钥来建立安全的连接,并对传输的数据进行加密和解密,以防止未经授权的访问和篡改。根据文章操作,生成以下四个文件用于存储与 SSL 相关的密钥、证书和信任的根证书。client.keystor…