kafka性能调优解密(二)-- Producer端
Producer篇
1 acks
1.1 参数描述
1.2 原理分析
Ack为0的时候应该性能最优,但没有可靠性保证;
Ack为1的时候只保证leader已经把数据写入,但没有确保各个副本已经写入,如果此时leader所在broker宕机,会丢失数据。
Ack为-1的时候,会保证所有的in-sync副本都写入成功才返回。这个参数性能最差,但可靠性是最高的
1.3 实测分析
1.在2个机器分别部署2个broker,创建10个分区的topic
2.客户端在另一个机器上进行发送消息测试。 通过修改消息长度和ACK不同的值,检查ack对性能的影响。
1G网卡下,采用New Producer共发1000000条,batch.size为16k。
Ack | message.sizes | MB.sec | nMsg.sec | 性能下降比 |
0 | 2048 | 88.4087 | 45265.2544 | / |
1 | 2048 | 67.4981 | 34559.0268 | 0.236522 |
-1 | 2048 | 20.8556 | 10678.0566 | 0.7641 |
0 | 4096 | 85.8007 | 21964.9878 | / |
1 | 4096 | 74.745 | 19134.7276 | 0.128853 |
-1 | 4096 | 19.0526 | 4877.4778 | 0.777943 |
0 | 8192 | 87.1386 | 11153.7432 | / |
1 | 8192 | 54.1993 | 6937.5069 | 0.378011 |
-1 | 8192 | 15.3464 | 1964.3394 | 0.823885 |
可以看出性能结果和原理分析中的结论是一致的,ack为0的时候最好,1次之,-1最差。
从测试数据中可以得到如下结论:
随着ACK的值增多,在集群中性能会下降,但消息可靠性增强,对可靠性和性能都要有要求的,推荐ack设置为1,这个也是默认值;业务允许节点异常时丢失少量数据,并且对性能要求很高的,可以用0。
2 batch.size
2.1 参数描述
参数 | 默认值 | 推荐值 | 说明 |
batch.size | 16384 | 524288 | producer将试图批处理消息记录,以减少请求次数。这将改善client与server之间的性能。这项配置控制默认的批量处理消息字节数。 |
2.2 原理分析
Producer创建一个BufferPool,totalSize为buffer.memory, 在这个pool里创建很多batch,每个batch大小就是batch.size。这个值越大,可以有效减少tcp传输次数。但是也不是越大越好,会造成内存浪费,因为linger.ms配置成0则会不等待batch.size装满就马上发送,导致每次发送batch buffer里有空闲;同时如果不够内存,会被block住影响性能
2.3 实测分析
1. 在2个机器分别部署2个broker,客户端在另一个机器上进行发送消息测试。 通过修改batch.size的值,检查这个参数对性能的影响。
2. 创建一个10个分区的topic
10G网卡下,2k数据,共发1000000条,线程数为10个
Batch.size为512k的时候,磁盘IO监控图为:
可以看出此时sda这一块盘的使用已达100%
10G网卡下,4k数据,共发1000000条,线程数为10个
Batch.size为512k的时候,磁盘IO监控图为:
分析结论:
1.从2k和4k的测试结果来看,峰值都出现在512k batch_size中。 此时查看磁盘,发现util 已经达到100%,磁盘成为瓶颈
2.batch_size过大,除了空间浪费外,还会导致BufferPool中可用的batch过少,导致发送速度快的时候分配内存不足的情况发生概率增大,发生被卡住
3 buffer.memory
3.1 参数描述
参数 | 默认值 | 推荐值 | 说明 |
buffer.memory | 33554432 | 128M~1G | producer可以用来缓存数据的内存大小。如果数据产生速度大于向broker发送的速度,producer会阻塞或者抛出异常,以“block.on.buffer.full”来表明。 |
3.2 原理分析
Producer对象创建BufferPool指定的内存大小,如果这个值设置的过小,会导致内存分配不足,在block.on.buffer.full为TRUE的情况下就会阻塞发送影响性能。设置过大的话会导致浪费内存
3.3 实测分析
1. 2个broker的场景下,创建10个分区的topic
2. 通过固定batch size,然后调大 buffer.memory,查看tps的变化
10G网卡下,2k数据,共发1000000条,线程数为10个,batchsize为512k
10G网卡下2k数据,共发1000000条,线程数为10个,batchsize为256k
可以看出buffer.memory设置过少,会导致tps很低,只有3w多;但设置很大,tps也不能一直提升。
分析结论:
1. buffer.memory 调的过小对性能会影响很大,因为内存不足就会导致发送被block(block.on.buffer.full为TRUE)
2. 设置过大的buffer.memory对性能提高帮助不是很大,只要够用就好。 可以根据batch size比默认值提高多少倍,而相应提高buffer.memory多少倍即可
4 send.buffer.bytes
4.1 参数描述
参数 | 默认值 | 推荐值 | 说明 |
send.buffer.bytes | 131072 | 默认值或者略大于带宽*时延 | TCP send缓存大小,当发送数据时使用 |
4.2 原理分析
TCP窗口
1、接收窗口
1)泛指接收缓冲区的大小。
2)接收缓冲区能够接收的数据字节数(接收缓冲区空出的字节数),实质上就是接收缓冲区的大小减去未送往应用层数据部分。又称为通告窗口。
2、发送窗口
1)泛指发送缓冲区的大小。
2)可发送的数据就处于发送窗口中,发送窗口大小指的就是可发送的数据量。
什么是BDP
BDP:Bandwidth Delay Product,即带宽时延乘积。
BDP=带宽×时延
带宽:是指瓶颈带宽,无线网络中一般空口是瓶颈,因此对应空口带宽。
时延:是指系统的环回时长RTT0,即:TCP
发出一个数据包到收到对应ACK的时长,约
等于PING环回时长。
在TCP序号-时间图上,以带宽为斜率画一个直角三角形,其斜边的斜率等于带宽,水平直角边的长度等于时延RTT0,则垂直直角边的长度就等于BDP。
TCP窗口与BDP的关系
1. TCP窗口< BDP
受限于TCP窗口大小,TCP速率达不到带宽。
TCP稳态速率=TCP窗口/RTT0<BDP/RTT0=带宽
TCP稳态速率随着TCP窗口的增大而增大,直至TCP窗口=BDP。
2. TCP窗口= BDP
TCP稳态速率=瓶颈带宽。
3. TCP窗口> BDP
当TCP窗口>BDP时,TCP稳态速率会不会进一步增大而超过瓶颈带宽呢?当然不会,速率还是会稳定在瓶颈带宽。
那会带来什么影响呢? RTT的增大!
RTT=TCP窗口/带宽
TCP缓冲区大小的设置原则
原则如下:
1、发送缓冲区和接收缓冲区的大小一般设置为相同的值。
2、缓冲区的大小一般设置为略大于BDP。
TCP缓冲区设置过大越大越好吗?
缓冲区设置过大会导致RTT增加,带来两个弊端:
1)丢包重传时速率恢复会变慢,因为重传包也会在缓冲区中排队发送。
2)会导致RTT测量变得迟钝,无法跟上系统时延的变化,造成无谓的重传或重传不及时。
4.3 实测分析
1. 2个broker 创建10个分区的topic
2. 在上面batch_size最好为512k 和 默认值的情况下,调整send.buffer.bytes,查看性能
10G网卡下,2k数据,共发1000000条,线程数为10个,batchsize为16k, buffer.memory为32M
10G网卡下,2k数据,共发1000000条,线程数为10个,batchsize为512k, buffer.memory为1024M
其中实测时延为0.032ms,带宽为10G,那么:
BDP = 10G * 0.032ms = 337k
从上面的测试可以看出128k~512k的send buffer,性能已经在峰值附近
结论:
1. send buffer采用默认值与broker 的receiver buffer默认值(100k)相对,性能在这个场景下是峰值
2. 可以根据BDP的计算公式,然后配置send buffer与receiver buffer略大于BDP大小
5. receive.buffer.bytes
5.1 参数描述
参数 | 默认值 | 推荐值 | 说明 |
receive.buffer.bytes | 32768 | 默认值 | TCP receive缓存大小,当阅读数据时使用 |
5.2 原理分析
生产者的Receiver buffer 一般对生产者影响不是很大,因为只有响应信息返回。
5.3 实测分析
1. 2个broker 创建10个分区的topic
2. 在上面batch_size最好为512k 和 默认值的情况下,调整receive.buffer.bytes,查看性能
10G网卡下,2k数据,共发1000000条,线程数为10个,batchsize为512k, bufferMem为32M, send.buffer为128k
结论:
与理论分析差不多,设置比较小对性能也影响不大,采用默认值即可
【版权声明】本文为华为云社区原创内容,未经允许不得转载,如需转载请发送邮件至hwclouds.bbs@huawei.com;如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
- 点赞
- 收藏
- 关注作者
评论(0)