主要做了4点优化,带来的效果非常明显,特别记下优化过程做的事。
numactl
这个优化主要针对服务器cpu架构是 NUMA 的情况。kafka 进程启动是通过 systemd 来启动的,配置 ExecStart
时,加上/usr/bin/numactl --interleave=all
,如:
ExecStart=/usr/bin/numactl --interleave=all /usr/local/kafka/bin/kafka-server-start.sh /usr/local/kafka/config/server.properties
在Interleave
模式下的程序性能是要比默认的亲和模式要高,有时甚至能高达30%。究其根本原因是 Linux 服务器的大多数 workload 分布都是随机的:即每个线程在处理各个外部请求对应的逻辑时,所需要访问的内存是在物理上随机分布的。而Interleave
模式就恰恰是针对这种特性将内存 page 随机打散到各个 CPU Core 上,使得每个 CPU 的负载和 Remote Access
的出现频率都均匀分布。
线程数配置
这里配置主要是测试测出来的,测试方法是使用不同数量的线程数的组合,观察集群在同一个压测参数下的表现。测试环境:两个CPU,每个CPU有24个核,每个CPU的本地内存是32G
最好的配置如下:
num.network.threads=24
num.io.threads=48
num.replica.fetchers=3
线程配置优先级
配置 systemd 的时候加上Nice=-20
Nice的含义如下:
Nice=
Sets the default nice level (scheduling priority) for executed
processes. Takes an integer between -20 (highest priority) and 19
(lowest priority). See setpriority(2) for details.
加上的目的是通过设置Nice的值配置最高优先级,让进程或线程持久地运行在指定的cpu上,也能防止进程或线程的切换。
微批次生产消息
这部分主要是该 kafka 生产者生产时做微批次化处理,所谓微批次化处理是指:producer每次发送前先等待30ms,而30ms之后producer将缓存的消息一次性发送。
producer累积消息一般仅仅是将消息发送到内存中的缓冲区,而发送消息却需要涉及网络I/O传输。内存操作和I/O操作的时间量级是不同的,前者通常是几百纳秒级别,而后者从毫秒到秒级别不等。
后面通过监控机器上的资源情况,例如内存,每台机器只用到14G多的内存,包括进程内存和文件 cache/buffer,显然这里 30ms 的阈值设置得太高了,后面可以改为10ms。
优化结果
1、减少了耗时,100+ms的生产发送耗时的出现频率降低
2、kafka 集群资源使用量大幅下降,尤其是内存部分,由以前每个机器的满内存使用量到现在每个机器只使用了内存总量的5分之一
参考资料
1、NUMA架构的CPU -- 你真的用好了么?
2、消息队列中吞吐量和处理速度这两个指标的困惑?
3、认清性能问题
4、进程和线程的优先级
本文由 Chakhsu Lau 创作,采用 知识共享署名4.0 国际许可协议进行许可。
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。