kafka性能调优解密(一)-- Broker端
Broker篇
1 网络模型3个相关参数
1.1 参数描述
参数 | 默认值 | 推荐值 | 说明 |
num.network.threads | 3 | 默认值 | server用来处理网络请求的网络线程数目;一般你不需要更改这个属性。 |
num.io.threads | 8 | 默认值 | server用来处理请求的I/O线程的数目;这个线程数目至少要等于硬盘的个数。 |
queued.max.requests | 500 | 默认值 | 在网络线程停止读取新请求之前,可以排队等待I/O线程处理的最大请求个数。 |
1.2 原理分析
Kafka的内部结构图如下:
Kafka的内部结构图如下:
其中num.network.threads是控制上图中的Processor Thread的个数, num.io.threads是控制API Thread的个数,queued.max_requests是控制Request Channel队列的容量。
1. 调大num.network.threads能够增加处理网络io请求,但不读写具体数据,基本没有io等待。但如果过大,会带来线程切换的开销。
2. 增大queued.max.requests能够缓存更多的请求,以撑过业务峰值。如果过大,会造成内存的浪费。
3. 增大num.io.threads能提升线程处理能力,如果过大会代理线程切换开销影响处理能力。同时至少要等于硬盘的个数。
1.3 实测分析
num.network.threads、num.io.threads和queued.max.requests 这三个参数是kafka网络模型的相关参数,所以这里一起测试。 模拟一定的压力,使得API threads线程处理不过来,request channel队列阻塞,性能开始下降。此时增大queue.max.requests或者增加API threads,查看性能情况
1G网卡下,10分区,2k数据,发送1000000, ack都为1, 3个Producer与3个Consumer一起跑, Consumer每次从队列开始读取数据
测试数据如下:
num.network.threads | num.io.threads | queued.max.requests | Producer nMsg.sec | Consumer nMsg.sec |
3 | 8 | 1 | 48768.5443 | 48985.088 |
3 | 8 | 250 | 50942.3841 | 52804.523 |
3 | 8 | 500 | 51303.0474 | 55146.401 |
3 | 8 | 1000 | 51956.0971 | 54461.271 |
3 | 1 | 1 | 50699.6045 | 48399.7216 |
从queued.max.requests值由1增加到1000,可以看出通过调大queue个数,性能可以稍稍提高6%左右
修改num.io.threads个数,性能影响不大。
10G网卡 下,100分区,2k数据,发送1000000, ack都为1, 10个Producer与10个Consumer一起跑, Consumer每次从队列开始读取数据,Producer BatchSize 为512M
num.network.threads | num.io.threads | queued.max.requests | Producer nMsg.sec | Consumer nMsg.sec |
3 | 8 | 1 | 203500.2035 | 139385.4383 |
3 | 8 | 1000 | 228206.2985 | 139567.3412 |
50 | 8 | 1 | 187441.4246 | 137869.9555 |
50 | 8 | 1000 | 229042.6019 | 151199.0081 |
取queued.max.requests的极端情况分别为1和1000,在不同的压力下, Producer性能能提升10%。 如果把num.network.threads调大,这两者的差距就更大达到22%
从数据得到的结论:
1.从上面的测试来看,3个线程的压力下,就算queued.max.requests设置为1,broker也能很快处理,不会造成性能剧烈下降。
2.10G 网卡下, queued.max.requests设置为1 与设置为1000比较,能提升22%。
3.按照目前的压力来看,用默认值就可以满足业务要求,发现性能瓶颈可以调大这三个参数就可以。
2 复制3个相关参数
2.1 参数描述
参数 | 默认值 | 推荐值 | 说明 |
replica.socket.receive.buffer.bytes | 64*1024 | 256k~2M | 备份时向leader发送网络请求时的socket receive buffer |
replica.fetch.max.bytes | 1024*1024 | 根据业务实际配置 | 备份时每次fetch的最大值 |
num.replica.fetchers | 1 | 默认值 | 从leader备份数据的线程数 |
2.2 原理分析
1.replica.socket.receive.buffer.bytes: 同TCP buffer的分析,不少于BDP 窗口大小,时延高的可以设大一点2.replica.fetch.max.bytes: 不得少于发往broker消息的最大长度(message.max.bytes),需要根据业务实际消息的大小,然后设大一点即可。
3. num.replica.fetchers: 复制fetch线程设置大一点可以提升获取性能,同时增加备机的IO并行性,但设置太大也没用反而导致空闲,这个同Consumer的fetch thread一样。
在ACK=1的情况下,Produce/Consumer的性能与复制关系不是很大,除非受到网络的瓶颈。
2.3 实测分析
单独调大receiver buffer参数:
replica.socket.receive.buffer.bytes | replica.fetch.max.bytes s | num.replica.fetchers | Producer nMsg.sec | Consumer nMsg.sec |
65536 | 1048576 | 1 | 141602.9453 | 140684.5711 |
262144 | 1048576 | 1 | 143843.5 | 136843.83 |
2097152 | 1048576 | 1 | 143287 | 141113.38 |
单独调大rep_fetch_max_bytes:
replica.socket.receive.buffer.bytes | replica.fetch.max.bytes s | num.replica.fetchers | Producer nMsg.sec | Consumer nMsg.sec |
65536 | 1048576 | 1 | 141602.9453 | 140684.5711 |
65536 | 4194304 | 1 | 163345.312 | 129623.2285 |
65536 | 8388608 | 1 | 148170.0993 | 143096.3181 |
单独调大num.replica.fetchers:
replica.socket.receive.buffer.bytes | replica.fetch.max.bytes s | num.replica.fetchers | Producer nMsg.sec | Consumer nMsg.sec |
65536 | 1048576 | 1 | 141602.9453 | 140684.5711 |
65536 | 1048576 | 5 | 161733.7862 | 142486.6775 |
65536 | 1048576 | 10 | 150330.7276 | 137249.5196 |
分析结论
1. 单独调这些参数,性能并没用发生比较大的变化,因为正常测试存在波动
2. replica.socket.receive.buffer.bytes 跟Consumer的 socket.receiver.buffer.bytes 尽量一致就可以
3. replica.fetch.max.bytes 根据业务最大消息来配置,稍微大一点就可以了
4. num.replica.fetchers 默认1个线程就足够了,否则复制会比较占网络流量
3 TCP相关参数
原理分析和理论指导值同Producer端的TCP参数。具体参考下篇producer端
【版权声明】本文为华为云社区原创内容,未经允许不得转载,如需转载请发送邮件至hwclouds.bbs@huawei.com;如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
- 点赞
- 收藏
- 关注作者
评论(0)