kafka性能调优解密(二)-- Producer端

网友投稿 849 2022-05-28

Producer篇

1  acks

Ack为0的时候应该性能最优,但没有可靠性保证;

Ack为1的时候只保证leader已经把数据写入,但没有确保各个副本已经写入,如果此时leader所在broker宕机,会丢失数据。

Ack为-1的时候,会保证所有的in-sync副本都写入成功才返回。这个参数性能最差,但可靠性是最高的

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

参数

默认值

推荐值

说明

batch.size

16384

524288

producer将试图批处理消息记录,以减少请求次数。这将改善client与server之间的性能。这项配置控制默认的批量处理消息字节数。

不会试图处理大于这个字节数的消息字节数。

发送到brokers的请求将包含多个批量处理,其中会包含对每个partition的一个请求。

较小的批量处理数值比较少用,并且可能降低吞吐量(0则会仅用批量处理)。较大的批量处理数值将会浪费更多内存空间,这样就需要分配特定批量处理数值的内存大小。

Producer创建一个BufferPool,totalSize为buffer.memory, 在这个pool里创建很多batch,每个batch大小就是batch.size。这个值越大,可以有效减少tcp传输次数。但是也不是越大越好,会造成内存浪费,因为linger.ms配置成0则会不等待batch.size装满就马上发送,导致每次发送batch buffer里有空闲;同时如果不够内存,会被block住影响性能

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

参数

默认值

推荐值

说明

buffer.memory

33554432

128M~1G

producer可以用来缓存数据的内存大小。如果数据产生速度大于向broker发送的速度,producer会阻塞或者抛出异常,以“block.on.buffer.full”来表明。

这项设置将和producer能够使用的总内存相关,但并不是一个硬性的限制,因为不是producer使用的所有内存都是用于缓存。一些额外的内存会用于压缩(如果引入压缩机制),同样还有一些用于维护请求。

Producer对象创建BufferPool指定的内存大小,如果这个值设置的过小,会导致内存分配不足,在block.on.buffer.full为TRUE的情况下就会阻塞发送影响性能。设置过大的话会导致浪费内存

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

参数

默认值

推荐值

说明

send.buffer.bytes

131072

默认值或者略大于带宽*时延

TCP send缓存大小,当发送数据时使用

TCP窗口

1、接收窗口

1)泛指接收缓冲区的大小。

2)接收缓冲区能够接收的数据字节数(接收缓冲区空出的字节数),实质上就是接收缓冲区的大小减去未送往应用层数据部分。又称为通告窗口。

2、发送窗口

1)泛指发送缓冲区的大小。

2)可发送的数据就处于发送窗口中,发送窗口大小指的就是可发送的数据量。

BDP:Bandwidth Delay Product,即带宽时延乘积。

BDP=带宽×时延

带宽:是指瓶颈带宽,无线网络中一般空口是瓶颈,因此对应空口带宽。

时延:是指系统的环回时长RTT0,即:TCP

发出一个数据包到收到对应ACK的时长,约

等于PING环回时长。

在TCP序号-时间图上,以带宽为斜率画一个直角三角形,其斜边的斜率等于带宽,水平直角边的长度等于时延RTT0,则垂直直角边的长度就等于BDP。

1.       TCP窗口< BDP

受限于TCP窗口大小,TCP速率达不到带宽。

TCP稳态速率=TCP窗口/RTT0

TCP稳态速率随着TCP窗口的增大而增大,直至TCP窗口=BDP。

2.       TCP窗口= BDP

TCP稳态速率=瓶颈带宽。

3.       TCP窗口> BDP

kafka性能调优解密(二)-- Producer端

当TCP窗口>BDP时,TCP稳态速率会不会进一步增大而超过瓶颈带宽呢?当然不会,速率还是会稳定在瓶颈带宽。

那会带来什么影响呢? RTT的增大!

RTT=TCP窗口/带宽

原则如下:

1、发送缓冲区和接收缓冲区的大小一般设置为相同的值。

2、缓冲区的大小一般设置为略大于BDP。

TCP缓冲区设置过大越大越好吗?

缓冲区设置过大会导致RTT增加,带来两个弊端:

1)丢包重传时速率恢复会变慢,因为重传包也会在缓冲区中排队发送。

2)会导致RTT测量变得迟钝,无法跟上系统时延的变化,造成无谓的重传或重传不及时。

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

参数

默认值

推荐值

说明

receive.buffer.bytes

32768

默认值

TCP receive缓存大小,当阅读数据时使用

生产者的Receiver buffer 一般对生产者影响不是很大,因为只有响应信息返回。

1. 2个broker 创建10个分区的topic

2.  在上面batch_size最好为512k 和 默认值的情况下,调整receive.buffer.bytes,查看性能

10G网卡下,2k数据,共发1000000条,线程数为10个,batchsize为512k, bufferMem为32M, send.buffer为128k

结论:

与理论分析差不多,设置比较小对性能也影响不大,采用默认值即可

缓存 应用性能调优 Kafka 存储

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:大妈也能看懂的大数据分布式计算
下一篇:【“互联网+”大赛华为云赛道】GaussDB命题攻略:支持三种开发语言,轻松完成数据库缓冲池
相关文章