调优目标

Kafka 的性能 :

  • 吞吐量 (TPS) : Broker 或 Client 每秒能处理的字节数或消息数 (越大越好)
  • 延时 : 从 Producer 发送消息到 Broker 持久化完成的时间间隔 (越短越好) 或 端到端的延时 (End-to-End,E2E ) : 从 Producer 发送消息到 Consumer 成功消费该消息的总时长

优化漏斗

优化漏斗 :

  • 应用程序层 : 优化 Kafka 客户端应用程序代码。如 : 用合理的数据结构、缓存计算开销大的运算结果,复用构造成本高的对象。优化效果最为明显,也是较简单的
  • 框架层 : 合理设置 Kafka 参数。根据实际场景配置关键参数
  • JVM 层 : Kafka Broker 进程是普通的 JVM 进程,对 JVM 的优化
  • 操作系统层 : 对操作系统层的优化

在这里插入图片描述

基础性调优

挂载 (Mount) 文件系统时 , 禁掉 atime 更新 (access time,文件最后被访问的时间)

  • 记录 atime 要操作系统访问 inode 资源
  • 禁掉 atime 能避免 inode 访问时间的写入操作,减少文件系统的写操作数
  • 命令 : mount -o noatime

文件系统 : 用 ext4 或 XFS :

  • XFS 文件系统 : 具有高性能、高伸缩性等特点,适用生产服务器
  • ZFS 多级缓存的机制能改善 I/O 性能

swap 空间 : swappiness=1 ,防止 Linux 的 OOM Killer 随意杀掉进程

  • 临时设置 : sudo sysctl vm.swappiness=N
  • 永久生效,修改 /etc/sysctl.conf 文件,增加 vm.swappiness=N ,重启机器

操作系统层面 :

  • ulimit -n :太小,会有 Too Many File Open 错误
  • vm.max_map_count : 太小,当主题数过多,会有 OutOfMemoryError:Map failed 错误
  • 生产环境适当调大,修改 /etc/sysctl.conf 文件,增加 vm.max_map_count=655360,执行 sysctl -p 生效

操作系统页缓存 :

  • Kafka 页缓存越大越好,至少保证一个日志段的大小
  • log.segment.bytes (默认 1GB)
  • Kafka 将日志段全部放入页缓存,能让消费者命中页缓存,避免磁盘 I/O

JVM 层调优

JVM 调优 : 设置堆大小/ GC 收集器的选择

Broker 设置堆大小 : 经验值 : JVM 堆大小 = 6~8GB

  • 精确调整 : 关注 Full GC 后,堆上存活对象的总大小,将把堆大小 = 该值的 1.5~2 倍
  • 手动 Full GC : jmap -histo:live <pid>

GC 收集器用 G1 收集器

  • 避免 Full GC 出现。G1 的 Full GC 是单线程运行,非常慢
  • 当 Kafka 出现 Full GC,配置 -XX:+PrintAdaptiveSizePolicy,查看谁导致 Full GC
  • 用 G1 问题 : 大对象 (Large Object) (错误 : too many humongous allocations) : 至少占半个区域 (Region) 大小的对象
  • 例子 : 区域尺寸是 2MB,超过 1MB 对象是大对象
  • 解决方法 : 适当增加区域大小,-XX:+G1HeapRegionSize=N
  • 当 Kafka 的消息体特别大时,就容易出现大对象分配问题

Broker 调优

Broker 端调优 : 保持客户端版本和 Broker 端版本一致

  • Producer、Consumer、Broker 版本相同,能享受 Zero Copy
  • 低版本 Consumer 要与 Producer、Broker 交互,就只能靠 JVM 堆进行中转,走慢速通道

image.png

应用层调优

  • 不频繁创建 Producer/Consumer : 构造这些对象的开销很大,尽量复用
  • 用完就关闭 : 对象会创建很多物理资源,如 : Socket 连接、ByteBuffer 缓冲区。及时关闭,能避免资源泄露
  • 利用多线程改善性能 : Java Producer 是线程安全,能在多个线程中共享同一个实例;而 Java Consumer 不是线程安全

性能指标调优

调优吞吐量

生产环境中,用较小的延时,来提升 TPS

  • Producer 累积消息时,会将消息发送到内存的缓冲区中,攒够消息数再通过网络 I/O 传输

调优 TPS

参数意义
Broker增加 num.replica.fetchersFollower 副本用多少个线程来拉取消息 (CPU充足,调大)
避免 Full GCFull GC 用 STW 的单线程收集,非常慢
Producer增加 batch.size增加消息批次大小
增加 linger.ms增加批次缓存时间
compression.type=lz4**zstd**减少网络 I/O ,提升吞吐量
acks = 0坚守同步时间,提升吞吐量
retries = 0不开启重试,提升吞吐量
多线程共享同个Producer , 增加 buffer.memory防止 TimeoutException:Failed to allocate memory within the configured max blocking time异常
Consumer多Consumer进程或线程同时消费多线程增加吞吐量
fetch.min.bytes=1KB让 Broker 一次返回多数据

调优延时

调优延时的参数 :

参数列表
Broker增加 num.replica.fetchers增加 Follower 副本的拉取速度,减少整个消息处理的延时
Producerlinger.ms = 0消息尽快发送出去,不要过多停留
compression.type = none压缩操作要消耗 CPU 时间,会增加消息发送的延时
acks = 1Follower 副本同步会降低Producer 吞吐量和增加延时
Consumerfetch.min.bytes = 1只要 Broker 有数据返回,就立刻返回给 Consumer,缩短Consumer 消费延时
Logo

Kafka开源项目指南提供详尽教程,助开发者掌握其架构、配置和使用,实现高效数据流管理和实时处理。它高性能、可扩展,适合日志收集和实时数据处理,通过持久化保障数据安全,是企业大数据生态系统的核心。

更多推荐