首页 > 其他分享 >面试官问:Kafka 会不会丢消息?怎么处理的?

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

时间:2024-06-20 17:10:14浏览次数:11  
标签:候选者 面试官 处理 Redis broker Kafka 消息

作者: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了,我相信破万是迟早的事情。

标签:候选者,面试官,处理,Redis,broker,Kafka,消息
From: https://www.cnblogs.com/paimianbaobao/p/18259041

相关文章

  • kafka 如何保证不重复消费又不丢失数据?
    作者:Java3y链接:https://www.zhihu.com/question/483747691/answer/2392949203来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。面试官:今天我想问下,你觉得Kafka会丢数据吗?候选者:嗯,使用Kafka时,有可能会有以下场景会丢消息候选者:比如说,我们用Produce......
  • 剖析 Kafka 消息丢失的原因
    目录前言一、生产者导致消息丢失的场景场景1:消息体太大解决方案:1、减少生产者发送消息体体积2、调整参数max.request.size场景2:异步发送机制解决方案:1、使用带回调函数的发送方法场景3:网络问题和配置不当解决方案:1、设置acks参数设置为"all"2、设置重试参数3、设置min.insync.......
  • 批处理调用mshta vbs模拟按键
    批处理模拟按键格,下面的功能是打开任务管理器mshtavbscript:createobject("wscript.shell").sendkeys("+^{esc}")(window.close)键参数退格键:{BACKSPACE}、{BS}或{BKSP}退格键:{BACKSPACE}、{BS}或{BKSP}BREAK:{BREAK}CAPSLOCK:......
  • KAFKA配置 SASL_SSL双重认证
    1.背景kafka提供了多种安全认证机制,主要分为SASL和SSL两大类。SASL:是一种身份验证机制,用于在客户端和服务器之间进行身份验证的过程,其中SASL/PLAIN是基于账号密码的认证方式。SSL:是一种加密协议,用于在网络通信中提供数据的保密性和完整性。它使用公钥和私钥来建立安全的连接,并......
  • 【AOP问题处理】:AopContext.currentProxy()方法异常处理:java.lang.IllegalStateExcept
    原因是代理对象内部方法的调用不会触发AOP代理。先看代码:自定义了一个注解:importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;//使用元注解......
  • 一站式统一返回值封装、异常处理、异常错误码解决方案—最强的Sping Boot接口优雅响应
    1.前言统一返回值封装、统一异常处理和异常错误码体系的意义在于提高代码的可维护性和可读性,使得代码更加健壮和稳定。统一返回值封装可以避免每一个接口都需要手工拼装响应报文;统一异常处理可以将异常处理的逻辑集中到一个地方,避免代码中出现大量的try-catch语句,降低了代码的......
  • 关于面试被面试官暴怼:“几年研究生白读” 的前因后果
      中午一个网友来信说自己和面试官干起来了,看完他的描述真是苦笑不得,这年头是怎么了,最近互联网CS消息满天飞,怎么连面试官都SB起来了呢?  大概是这样的:这位网友面试时被问及了Serializable接口的底层实现原理,因为这是一个标识性的空接口,大部分同学在学习时都秉持着会用就行......
  • drogon跨域问题和全局异常处理
    2024年6月20日12:21:11在main.cc里加入/***全局异常处理*/drogon::app().setExceptionHandler([](conststd::exception&e,constdrogon::HttpRequestPtr&req,......
  • PFTL.201C-20kN张力计压头故障处理
    故障处理1、维护措施(1)脉冲线绝缘防护。可控硅击穿的直接原因是其脉冲线窜入高压。事后对其他可控硅脉冲线开展了绝缘检查,并在脉冲线上增加绝缘套管,以消灭高压窜入的可能性。(2)定期除尘。可控硅、脉冲变等元件积尘可能引起接头之间的放电、局部短路,同时,元器件引线的积尘(特别......
  • 剖析 Kafka 消息丢失的原因
    文章目录前言一、生产者导致的消息丢失的场景场景1:消息太大解决方案:1、减少生产者发送消息体体积2、调整参数max.request.size场景2:异步发送机制解决方案:1、使用带回调函数的发送方法场景3:网络问题和配置不当解决方案:1、设置`acks`参数设置为"all"2、设置重试参数......