Kafka 调优
调优目标
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 堆进行中转,走慢速通道
应用层调优
- 不频繁创建 Producer/Consumer : 构造这些对象的开销很大,尽量复用
- 用完就关闭 : 对象会创建很多物理资源,如 : Socket 连接、ByteBuffer 缓冲区。及时关闭,能避免资源泄露
- 利用多线程改善性能 : Java Producer 是线程安全,能在多个线程中共享同一个实例;而 Java Consumer 不是线程安全
性能指标调优
调优吞吐量
生产环境中,用较小的延时,来提升 TPS
- Producer 累积消息时,会将消息发送到内存的缓冲区中,攒够消息数再通过网络 I/O 传输
调优 TPS
参数意义Broker增加
num.replica.fetchers
Follower 副本用多少个线程来拉取消息 (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 副本的拉取速度,减少整个消息处理的延时Producer
linger.ms = 0
消息尽快发送出去,不要过多停留
compression.type = none
压缩操作要消耗 CPU 时间,会增加消息发送的延时
acks = 1
Follower 副本同步会降低Producer 吞吐量和增加延时Consumer
fetch.min.bytes = 1
只要 Broker 有数据返回,就立刻返回给 Consumer,缩短Consumer 消费延时
版权归原作者 cpuCode 所有, 如有侵权,请联系我们删除。