当前位置: 首页 > news >正文

【八股消消乐】Kafka集群 full GC 解决方案

在这里插入图片描述

😊你好,我是小航,一个正在变秃、变强的文艺倾年。
🔔本专栏《八股消消乐》旨在记录个人所背的八股文,包括Java/Go开发、Vue开发、系统架构、大模型开发、具身智能、机器学习、深度学习、力扣算法等相关知识点,期待与你一同探索、学习、进步,一起卷起来叭!

目录

  • 题目
  • 答案
    • 优化生产者
      • 优化acks
      • 优化批次
      • 启用压缩
    • 优化broker
      • 优化 swap
      • 优化网络读写缓冲区
      • 优化磁盘 IO
      • 优化主从同步
      • 优化JVM

题目

💬技术栈:RocketMQ、Kafka、RabbitMQ

🔍简历内容:为解决xx业务高峰期响应时间长、客户端超时问题,通过优化acks、批次并将压缩算法从 Snappy 更换为 LZ4,提高生产者发送效率。经排查,kafka 集群触发了 full GC 之后,停顿时间就会很长,导致 Kafka 吞吐量显著下降,有时候还会导致 Kafka 认为主分区已经崩溃触发主从选举,通过调大 JVM 的堆,并且在堆很大的情况下,启用 G1 垃圾回收器解决了问题。

🚩面试问:Kafka 还有一些参数也对性能有影响,你能介绍一下你是如何优化的吗?


在这里插入图片描述

💡建议暂停思考10s,你有答案了嘛?如果你有不同题解,欢迎评论区留言、打卡。


答案

简历准备:

  • 你维护的业务在使用消息队列的时候,后面优化措施中提到的参数取值都是多少?
  • 你们公司消息队列的各个参数有没有被调过?为什么调?
  • 是否遇到过和消息队列有关的 Bug?如果有,那么怎么解决的?
  • 维护的业务使用消息队列时的 QPS 是多少

场景准备:高并发的消息队列使用场景,要求高效发送、高效消费,不然就会有问题,比如说出现消息积压或者生产者阻塞的问题。

整理思路:从消息队列的生产者、broker 和消费者这三方出发。

优化生产者

优化acks

场景:有一个系统在一个高并发场景下会发送消息到 Kafka,结果发现这个接口在业务高峰的时候响应时间很长,客户端经常遇到超时的问题

排查后:写这段代码的人直接复制了已有的发送消息代码,而原本人家的业务追求的是消息不丢,所以 acks 设置成了 all。实际上这个业务并没有那么严格的消息不丢的要求,完全可以把 acks 设置为 0。

效果:这么一调整,整个接口的响应时间就显著下降了,客户端那边也很少再出现超时的问题。

不过追求消息不丢失的业务场景就不能把 acks 设置为 0 或者 1,这时候就只能考虑别的优化手段,比如说优化批次。

优化批次

场景:生产者发送消息的性能问题。

排查后:因为发送性能太差,导致发送缓冲池已经满了,阻塞了发送者。这个时候我们注意到其实发送速率还没有达到 broker 的阈值,也就是说,broker 其实是处理得过来的。

解决方案:在这种情况下,最直接的做法就是加快发送速率,也就是调大 batch.size 参数,从原本的 100 调到了 500,就没有再出现过阻塞发送者的情况了。

在这里插入图片描述

当然,批次也不是说越大越好。

原因:批次大了的话,生产者这边丢失数据的可能性就比较大。而且批次大小到了一个地步之后,性能瓶颈就变成了 broker 处理不过来了,再调大批次大小是没有用的。最好的策略,还是通过压测来确定合适的批次大小


发送者被阻塞也可能是因为缓冲池太小

解决方案:调大缓冲池

原因:topic、分区太多,每一个分区都有一块缓冲池装着批量消息,导致缓冲池空闲缓冲区不足,这一类不是因为发送速率的问题导致的阻塞,就可以通过调大缓冲池来解决。

在这里插入图片描述

所以发送者阻塞要仔细分析,如果是发送速率的问题,那么调大发送缓冲区是治标不治本的。如果发送速率没什么问题,确实就是因为缓冲池太小引起的,就可以调大缓冲池。如果现实中,也比较难区别这两种情况,就可以考虑先调大批次试试,再调整缓冲池。

启用压缩

场景:Kafka 默认是不启用压缩的,为了进一步提高 Kafka 的吞吐量,我也开启了 Kafka 的压缩功能,使用了 LZ4 压缩算法。【为了进一步提高 Kafka 的吞吐量,我将压缩算法从 Snappy 换到了 LZ4。】

一定要做性能测试

优化broker

优化 swap

Kafka 是一个非常依赖内存的应用,所以可以调小 vm.swappniess 参数来优化内存。

为了优化 Kafka 的性能,可以调小 vm.swappiness。比如说调整到 10,这样就可以充分利用内存;也可以调整到 1,这个值在一些 linux 版本上是指进行最少的交换,但是不禁用交换。目前我们公司用的就是 10。

为什么不直接禁用 swap 呢?

物理内存总是有限的,所以直接禁用的话容易遇到内存不足的问题。我们只是要尽可能优化内存,如果物理内存真的不够,那么使用交换区也比系统不可用好

在这里插入图片描述

优化网络读写缓冲区

Kafka 也是一个网络 IO 频繁的应用,所以调整网络有关的读写缓冲区,效果也会更好。对应的参数有6个。

  • net.core.rmem_default 和 net.core.wmem_default:Socket 默认读写缓冲区大小。
  • net.core.rmem_max 和 net.core.wmem_max:Socket 最大读写缓冲区。
  • net.ipv4.tcp_wmem 和 net.ipv4.tcp_rmem:TCP 读写缓冲区。它们的值由空格分隔的最小值、默认值、最大值组成。可以考虑调整为 4KB、64KB 和 2MB。

回答模板:调大读写缓冲区。Scoket 默认读写缓冲区可以考虑调整到 128KB;Socket 最大读写缓冲区可以考虑调整到 2MB,TCP 的读写缓冲区最小值、默认值和最大值可以设置为 4KB、64KB 和 2MB。不过这些值究竟多大,还是要根据 broker 的硬件资源来确定。

优化磁盘 IO

Kafka 也是一个磁盘 IO 密集的应用,所以可以从两个方向优化磁盘 IO。
(1)使用 XFS 作为文件系统,它要比 EXT4 更加适合 Kafka。相比于 EXT4,XFS 性能更好。在同等情况下,使用 XFS 的 Kafka 要比 EXT4 性能高 5% 左右。XFS还有别的优点,例如扩展性更好,支持更多、更大的文件。
(2)禁用 Kafka 用不上的 atime 功能

优化主从同步

总结: 都调大,它们的效果,就是为了让从分区一批次同步尽可能多的数据

从分区和主分区数据同步的过程受到了几个参数的影响。

  • num.replica.fetchers:从分区拉取数据的线程数量,默认是1。你可以考虑设置成 3。
  • replica.fetch.min.bytes:可以通过调大这个参数来避免小批量同步数据
  • replica.fetch.max.bytes:这个可以调大,比如说调整到 5m,但是不要小于 message.max.byte,也就是不要小于消息的最大长度。
  • replica.fetch.wait.max.ms:如果主分区没有数据或者数据不够从分区的最大等待时间,可以考虑同步调大这个值和 replica.fetch.max.bytes。
    在这里插入图片描述

首先调整从分区的同步数据线程数量,比如说调整到 3,这样可以加快同步速率,但是也会给主分区和网络带宽带来压力。

其次是调整同步批次的最小和最大字节数量,越大则吞吐量越高,所以都尽量调大。

最后也可以调整从分区的等待时间,在一批次中同步尽可能多的数据。

不过调大到一定地步之后,瓶颈就变成了从分区来不及处理。或者调大到超过了消息的并发量,那么也没意义了。

Kafka 这种机制可以看作是典型的批量拉数据模型。在这个模型里面,要着重考虑的就是多久拉一次,没有怎么办,一次拉多少?在实现这种模型的时候,让用户根据自己的需要来设定参数是一个比较好的实践。

优化JVM

Kafka 是运行在 JVM 上的,所以理论上来说任何优化 Java 性能的措施,对 Kafka 也一样有效果。

优化 JVM:

(1)首先就是考虑优化 GC,即优化垃圾回收。而优化 GC 最重要的就是避免 full GC。full GC 是指整个应用都停下来等待 GC 完成。它会带来两方面影响。一方面是发送者如果设置 acks 为 1 或者 all,都会被阻塞,Kafka 吞吐量下降

在这里插入图片描述

(2)如果 full GC 时间太长,那么主分区可能会被认为已经崩溃了,Kafka 会重新选择主分区;而如果是从分区,那么它会被挪出 ISR,进一步影响 acks 设置为 all 的发送者

在这里插入图片描述

基本的思路就是调大 JVM 的堆,并且在堆很大的情况下,启用 G1 垃圾回收器

之前我们的 Kafka 集群还出过 GC 引发的性能问题。我们有一个 Kafka 的堆内存很大,有 8G,但是垃圾回收器还是用的 CMS。触发了 full GC 之后,停顿时间就会很长,导致 Kafka 吞吐量显著下降,并且有时候还会导致 Kafka 认为主分区已经崩溃,触发主从选举

优化思路:

(1)一个是考虑优化 CMS 本身,比如说增大老年代,但是这个治标不治本,可以缓解问题,但是不能根治问题。
(2)直接切换到 G1 回收器。G1 回收器果然表现得非常好,垃圾回收频率和停顿时间都下降了。


往期精彩专栏内容,欢迎订阅:

🔗【八股消消乐】20250711:浅尝Kafka性能优化
🔗【八股消消乐】20250630:消息队列优化—重复消费
🔗【八股消消乐】20250629:消息队列优化—消息丢失
🔗【八股消消乐】20250627:消息队列优化—消息积压
🔗【八股消消乐】20250625:消息队列优化—消息有序
🔗【八股消消乐】20250624:消息队列优化—延迟消息
🔗【八股消消乐】20250623:消息队列优化—系统架构设计
🔗【八股消消乐】20250622:Elasticsearch查询优化
🔗【八股消消乐】20250620:Elasticsearch优化—检索Labubu
🔗【八股消消乐】20250619:构建微服务架构体系—保证服务高可用
🔗【八股消消乐】20250615:构建微服务架构体系—链路超时控制
🔗【八股消消乐】20250614:构建微服务架构体系—实现制作库与线上库分离
🔗【八股消消乐】20250612:构建微服务架构体系—限流算法优化
🔗【八股消消乐】20250611:构建微服务架构体系—降级策略全总结
🔗【八股消消乐】20250610:构建微服务架构体系—熔断恢复抖动优化
🔗【八股消消乐】20250609:构建微服务架构体系—负载均衡算法如何优化
🔗【八股消消乐】20250608:构建微服务架构体系—服务注册与发现
🔗【八股消消乐】20250607:MySQL存储引擎InnoDB知识点汇总
🔗【八股消消乐】20250606:MySQL参数优化大汇总
🔗【八股消消乐】20250605:端午节产生的消费数据,如何分表分库?
🔗【八股消消乐】20250604:如何解决SQL线上死锁事故
🔗【八股消消乐】20250603:索引失效与优化方法总结
🔗【八股消消乐】20250512:慢SQL优化手段总结
🔗【八股消消乐】20250511:项目中如何排查内存持续上升问题
🔗【八股消消乐】20250510:项目中如何优化JVM内存分配?
🔗【八股消消乐】20250509:你在项目中如何优化垃圾回收机制?
🔗【八股消消乐】20250508:Java编译优化技术在项目中的应用
🔗【八股消消乐】20250507:你了解JVM内存模型吗?
🔗【八股消消乐】20250506:你是如何设置线程池大小?
🔗【八股消消乐】20250430:十分钟带背Duubo中大厂经典面试题
🔗【八股消消乐】20250429:你是如何在项目场景中选取最优并发容器?
🔗【八股消消乐】20250428:你是项目中如何优化多线程上下文切换?
🔗【八股消消乐】20250427:发送请求有遇到服务不可用吗?如何解决?

📌 [ 笔者 ]   文艺倾年
📃 [ 更新 ]   2025.7.11
❌ [ 勘误 ]   /* 暂无 */
📜 [ 声明 ]   由于作者水平有限,本文有错误和不准确之处在所难免,本人也很想知道这些错误,恳望读者批评指正!

在这里插入图片描述

http://www.dtcms.com/a/276670.html

相关文章:

  • pytorch深度学习—RNN-循环神经网络
  • 服务端高效处理拖拽排序
  • [创业之路-502]:企业管理层 - 什么是企业经营,什么是企业管理?什么是业务?
  • [Token]Token merging for Vision Generation
  • 2025全网最详细的软件测试面试八股文
  • 面试150 翻转二叉树
  • FreeRTOS内核实现与应用之0——编码风格
  • 【离线数仓项目】——电商域DWS层开发实战
  • 【AI大模型】部署优化量化:INT8压缩模型
  • 深入理解设计模式:原型模式(Prototype Pattern)
  • 深入解析5G核心网容灾:SMF在PCF全故障下的PDU会话处理机制
  • 绘制气候预报图:利用地理空间技术解锁气候洞察
  • 深大计算机游戏开发 实验二
  • Linux操作系统之进程间通信:共享内存
  • 商编轮巡作为一种策略,旨在帮助商户规避支付平台(如VX. ZFB) 的风控措施。这种策略通过轮换使用不同的商户编号(商编)来减少单一商户因频繁交
  • c++-base
  • ActionPeice-ICML2025-谷歌deepmind-生成式推荐中上下文感知分词技术
  • 深入浅出:RS232、RS485、UART、Modbus与差分信号、共模信号的那些事儿
  • 力扣刷题(第八十五天)
  • dubbo源码学习3-dubbo反射调用服务源码分析
  • Unity开发中常用的洗牌算法
  • 数据结构——散列表
  • 数据结构栈的实现(C语言)
  • C语言--原码、反码、补码转换
  • 知识宇宙-思考篇:AI大模型如何重塑软件开发流程?
  • Sentinel+nacos实现push模式规则持久化
  • Java生产带文字、带边框的二维码
  • matplotlib:饼图、环形图、爆炸式饼图
  • 五、深度学习——CNN
  • Raft 代码分析