被怼了:acks=all消息也会丢失?

消息队列是面试中一定会被问到的技术模块,虽然它在面试题占比不及并发编程和数据库,但也属于面试中的关键性问题。所以今天我们就来看一道,MQ 中高频,但可能会打破你以往认知的一道面试题。

所谓的关键问题指的是这道面试题会影响你整体面试结果。

我们在面试消息队列(Message Queue,MQ)时,尤其是面试 Kafka 时,经常会被问到:如何保证消息不丢失?

那么,我们的回答会分为以下 3 部分:

  1. 保证生产者消息不丢失
  2. 保证 Kafka 服务(器端)消息不丢失
  3. 保证消费者消息不丢失

只有保证这 3 部分消息都不丢失,才能保证 Kafka 整体消息不丢失。

因为 Kafka 消息的传递流程如下(总共包含 3 部分):
image.png

1.如何保证生产者消息不丢失?

那怎么保证生产者消息不丢失呢?

要搞明白这个事,我们就要先了解一下生产者发送消息的执行流程。

Kafka 生产者发送消息的执行流程如下:
image.png
默认情况下,所有的消息会先缓存到 RecordAccumulator 缓存中,再由 Sender 线程拉取消息发送到 Kafka 服务器端,通过 RecordAccumulator 和 Sender 线程的协作,实现了消息的批量发送、性能优化和异常处理等功能,确保了消息的高效可靠传输。

1.1 RecordAccumulator 缓存作用

  1. 暂存消息:RecordAccumulator 是 Kafk a生产者中的一个关键组件,它充当了一个缓存的角色,用于暂存主线程(Main Thread)发送过来的消息。这些消息在 RecordAccumulato r中等待被 Sender 线程批量发送。
  2. 批量发送:RecordAccumulator 通过批量收集消息,减少了单个消息发送的网络请求次数,从而提高了发送效率。Sender 线程可以从 RecordAccumulator 中批量获取消息,一次性发送到 Kafka 集群,减少了网络传输的资源消耗。
  3. 性能优化:RecordAccumulator的缓存大小可以通过生产者客户端参数 buffer.memory 进行配置(默认值为 32MB)。合理的缓存大小设置可以平衡内存使用与发送效率,达到最优的性能表现。
  4. 内存管理:如果 RecordAccumulator 的缓存空间被占满,生产者再次调用 send() 方法发送消息时,会出现阻塞(默认阻塞时间为 60 秒,可通过 max.block.ms 参数配置)。如果阻塞超时,则会抛出异常。这种机制有助于防止生产者因为无限制地缓存消息而耗尽系统资源。
  5. ByteBuffer 复用:为了减少频繁创建和释放 ByteBuffer 所造成的资源消耗,RecordAccumulator 内部还维护了一个 BufferPool,用于实现 ByteBuffer 的复用。特定大小的 ByteBuffer 会被缓存起来,以便后续消息发送时重复使用。

1.2 Sender 线程作用

  1. 拉取消息:Sender 线程是 Kafka 生产者中的一个后台线程,它负责从 RecordAccumulator 中拉取缓存的消息。Sender 线程会定期轮询 RecordAccumulator,检查是否有新消息需要发送。
  2. 批量构建请求:当 Sender 线程发现有新消息需要发送时,它会构建一个或多个 ProducerRequest 请求。每个请求包含多个消息,以便进行有效的批量发送。这种批量发送机制可以显著提高网络传输效率。
  3. 发送消息到 Kafka 集群:Sender 线程将构建的 ProducerRequest 请求发送到 Kafka 集群的相应分区。它会根据分区的 Leader 节点信息,将消息发送给对应的 Broker 节点。
  4. 异常处理:在消息发送过程中,可能会出现网络故障、分区不可用等异常情况。Sender 线程负责处理这些异常,例如进行重试、重新连接等操作,以确保消息的可靠发送。
  5. 状态更新:一旦消息被成功接收并记录在 Kafka Broker 的日志中,Sender 线程会通知 RecordAccumulator 更新消息的状态。这样,生产者就能够知道哪些消息已经被成功发送,哪些消息还需要重试发送。

2.生产者消息丢失的两种场景

了解了 Kafka 生产者发送消息的流程之后,我们就能知道在这个环节丢失消息的情况有以下两种:

  1. 网络抖动(消息不可达):生产者与 Kafka 服务端之间的链路不可达,发送超时。此时各个节点的状态是正常,但消费端就是没有消费消息,就像消息丢失了一样。
  2. 无消息确认(ack):生产者消息发送之后,无 ack 消息确认,直接返回消息发送成功,但消息发送之后,Kafka 服务宕机或掉电了,导致消息丢失。

怎么解决这个问题呢?

2.1 网络波动问题处理

网络波动的话设置消息重试即可,因为网络抖动消息不可达,所以只要配置了重试次数,那么就会消息重试以此来保证消息不丢失。

在 Spring Boot 项目中,只需要在配置文件 application.yml 中,设置生产者的重试次数即可:

spring:  
  kafka:  
    producer:  
      retries: 3

2.2 消息确认设置

Kafka 生产者的 ACK(Acknowledgment)机制是指生产者在发送消息到 Kafka 集群后,等待确认的方式。这个机制决定了生产者何时认为消息已经成功发送,并直接影响到消息的可靠性和性能。

Kafka 生产者的 ACK 机制主要有以下三种类型。

① acks=0

生产者在将消息发送到网络缓冲区后,立即认为消息已被提交,不会等待任何来自服务器的响应。这时设置的重试次数 retries 无效。

特点

  • 最高性能:由于不需要等待任何确认,因此具有最高的吞吐量。
  • 最低可靠性:消息可能会在发送过程中丢失,生产者无法知道消息是否成功到达服务器。

适用场景:对消息可靠性要求不高,但追求极致性能的场景。

② acks=1

生产者在将消息发送到主题的分区 leader 后,等待 leader 的确认,即认为消息已被提交(此时 leader 写入成功,并没有刷新到磁盘),不用等待所有副本的确认。

特点

  • 中等可靠性和性能:提供了一定程度的可靠性,因为只有领导者副本确认消息后生产者才会收到确认。但如果领导者副本在确认后发生故障,而消息还未复制到其他副本,则消息可能会丢失。
  • 性能与可靠性平衡:在生产者性能和消息可靠性之间提供了一个折衷方案。

适用场景:适用于传输普通日志,允许偶尔丢失少量数据的场景。

③ acks=all 或 acks=-1

生产者需要等待所有同步副本(ISR, In-Sync Replicas)都成功写入消息后,才认为消息已被提交。

特点

  • 最高可靠性:只有当所有同步副本都确认接收到消息后,生产者才会收到确认,确保了消息的可靠性。
  • 较低性能:由于需要等待所有同步副本的确认,因此可能会导致消息发送的延迟增加,从而影响性能。

适用场景:适用于对消息可靠性要求极高的场景,如金融交易等关键任务应用。

在 Spring Boot 项目中,acks 可以在配置文件 application.yml 中设置:

spring:  
  kafka:  
    producer:  
      acks: all

3.acks=all消息一定不会丢失吗?

正常情况下当我们设置 acks=all 时,其实是可以保证数据不丢失了。但是有一种特殊情况,如果 Topic 只有一个 Partition(分区时),也就是只有一个 Leader 节点时,此时消息也是会丢失的

如果只有一个 Leader 节点,acks=all 的设置和 acks=1 的设置效果基本类似,当 Leader 确认消息之后,还没来得及将消息刷到磁盘之前宕机了,那么就会造成消息丢失。

万事必有妖,当面试官用疑问语句问你时,答案基本是否定的。如果是确定的话,面试官可能也就不会再问你了,所以当你听到一个有悖于常识的问题时,先努力思考这个问题还有没有其他答案。

课后思考

Kafka 服务器端和消费者如何保证消息不丢失呢?

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。

原创作者: vipstone 转载于: https://www.cnblogs.com/vipstone/p/18345747
以下是对提供的参考资料的总结,按照要求结构化多个要点分条输出: 4G/5G无线网络优化与网规案例分析: NSA站点下终端掉4G问题:部分用户反馈NSA终端频繁掉4G,主要因终端主动发起SCGfail导致。分析显示,在信号较好的环境下,终端可能因节能、过热保护等原因主动释放连接。解决方案建议终端侧进行分析处理,尝试关闭节电开关等。 RSSI算法识别天馈遮挡:通过计算RSSI平均值及差值识别天馈遮挡,差值大于3dB则认定有遮挡。不同设备分组规则不同,如64T和32T。此方法可有效帮助现场人员识别因环境变化引起的网络问题。 5G 160M组网小区CA不生效:某5G站点开启100M+60M CA功能后,测试发现UE无法正常使用CA功能。问题原因在于CA频点集标识配置错误,修正后测试正常。 5G网络优化与策略: CCE映射方式优化:针对诺基亚站点覆盖农村区域,通过优化CCE资源映射方式(交织、非交织),提升RRC连接建立成功率和无线接通率。非交织方式相比交织方式有显著提升。 5G AAU两扇区组网:与三扇区组网相比,AAU两扇区组网在RSRP、SINR、下载速率和上传速率上表现不同,需根据具体场景选择适合的组网方式。 5G语音解决方案:包括沿用4G语音解决方案、EPS Fallback方案和VoNR方案。不同方案适用于不同的5G组网策略,如NSA和SA,并影响语音连续性和网络覆盖。 4G网络优化与资源利用: 4G室分设备利旧:面对4G网络投资压减与资源需求矛盾,提出利旧多维度调优策略,包括资源整合、统筹调配既有资源,以满足新增需求和提质增效。 宏站RRU设备1托N射灯:针对5G深度覆盖需求,研究使用宏站AAU结合1托N射灯方案,快速便捷地开通5G站点,提升深度覆盖能力。 基站与流程管理: 爱立信LTE基站邻区添加流程:未提供具体内容,但通常涉及邻区规划、参数配置、测试验证等步骤,以确保基站间顺畅切换和覆盖连续性。 网络规划与策略: 新高铁跨海大桥覆盖方案试点:虽未提供详细内容,但可推测涉及高铁跨海大桥区域的4G/5G网络覆盖规划,需考虑信号穿透、移动性管理、网络容量等因素。 总结: 提供的参考资料涵盖了4G/5G无线网络优化、网规案例分析、网络优化策略、资源利用、基站管理等多个方面。 通过具体案例分析,展示了无线网络优化中的常见问题及解决方案,如NSA终端掉4G、RSSI识别天馈遮挡、CA不生效等。 强调了5G网络优化与策略的重要性,包括CCE映射方式优化、5G语音解决方案、AAU扇区组网选择等。 提出了4G网络优化与资源利用的策略,如室分设备利旧、宏站RRU设备1托N射灯等。 基站与流程管理方面,提到了爱立信LTE基站邻区添加流程,但未给出具体细节。 新高铁跨海大桥覆盖方案试点展示了特殊场景下的网络规划需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值