Kafka Producer性能模型主要包含以下机制。
1.背压机制
当生产者的发送速率超过Broker的接收速率,或者网络拥塞时,生产者内部的缓冲区可能会填满。此时,生产者会根据buffer.memory设定的最大内存限制,暂停从应用程序接收新消息,直到缓冲区中的消息被发送出去,腾出足够的空间,这种机制称为背压控制,它可以防止生产者无限制地占用内存,导致系统资源耗尽。
背压机制主要涉及以下一个参数。
1.1.buffer.memory
producer端可缓存消息的最大字节数,默认值为33554432,表示32MB。
如果记录发送到broker的速率比记录写入缓存的速率小,producer会处于block状态,如果超过max.block.ms(默认值1分钟),就会抛异常。
这个配置应当基本接近producer可用的内存,小于producer进程的Xmx。但是这个配置并不是一个严格的边界值,因为数据压缩以及发送请求也需要一定的内存空间。
2.Producer批量机制
主要涉及以下两个参数
2.1.batch.size
批量的大小,一批数据的字节数,默认是16KB。如果此值为0,则禁止批量机制,消息会一条一条发送。
为了减少请求发送次数,Producer会尽可能批量发送消息到Broker,这提升了客户端和服务端的性能。
当一个批次的数据大于此值时,这个批次不会接收新的消息,会被发送到缓冲或Broker。
一个Producer可能同时会有多个batches,每个batch对应一个分区。
小的batch.size值会使批量发送变频繁,降低吞吐量。
而大的batch.size值会造成对内存资源的浪费,因为Producer总是会提前申请到batch.size的缓冲区用于接收持续的消息。
注意,当前参数设置了批量的下限。如果当前批量的大小小于此值,则需要根据linger.ms参数来确定是否发送到缓冲区或Broker。
2.2.linger.ms
如果一个批量迟迟没有达到batch.size的大小,sender会等待linger.ms设置的时间,到了后,就会发送数据。单位是毫秒,默认为0,表示没有延迟。
Producer会把消息请求聚合成一个批量请求。
通常,在较低负载情况下,消息到达的效率比发送的效率要低。但在一些场景中,即使是中等的压力,客户端也想降低请求的数量。这个配置就可以满足这种需求,通过增加延迟来实现,也就是不立刻发送消息,producer会等待linger.ms的时间然后把批量请求发送出去。这类似于TCP中的nagle算法。
这个配置只是确定了等待的上限,一旦某个分区的批量请求达到batch.size,不管linger.ms是多少,这个请求还是会被立刻发送。但是,如果某个分区的批量请求迟迟打不到batch.size,producer等待linger.ms后,仍然会把这个批量请求发送出去。
如果把linger.ms设置为5,我们可能降低发送请求速率,但这里就会导致消息有最大5ms的延迟,对消息的实时性是个挑战。
2.3.max.request.size
一个请求的最大字节数,默认为1048576,表示1MB。
批量机制还需要注意这个参数,因为批量请求的大小也是不能超过max.request.size配置值的,这里比较的是未被压缩的请求大小。
3.Socket Buffer
这个属于网络层面的缓存,可以在客户端设置,也可以在服务端设置。
3.1.kafka client通用参数
可以在connector、consumer和producer中设置,主要有以下两个参数
3.1.1.send.buffer.bytes
发送数据时,配置TCP发送缓冲大小,和SO_SNDBUF一样。默认131072,表示128KB。如果设置为-1,表示使用操作系统SO_SNDBUF默认值。
3.1.2.receive.buffer.bytes
接收数据时,配置TCP接收缓冲大小,可用SO_RCVBUF表示。默认32768,表示32KB。如果设置为-1,表示使用操作系统SO_RCVBUF默认值。
3.2.Kafka Server端参数
需要在KafkaBroker的配置文件server.properties中设置,有三个参数:
3.2.1.socket.send.buffer.bytes
创建Socket时,SO_SNDBUF参数值。默认102400,表示100KB。如果设置为-1,表示使用操作系统层面发送缓冲大小配置。
3.2.2.socket.receive.buffer.bytes
服务端Socket缓冲大小SO_RCVBUF。默认102400,表示100KB。。如果设置为-1,表示使用操作系统SO_SNDBUF默认值。
3.2.3.replica.socket.receive.buffer.bytes
副本同步数据时创建的socket接收缓冲大小。默认为65536,表示64KB。
4.压缩机制
如果配置了compression.type参数,生产者在发送消息批次之前对其进行压缩。这不仅可以减少网络传输的数据量,降低带宽消耗,还能进一步利用批量发送的优势,因为压缩通常对大批量数据的效果更好。
4.1.compression.type
compression.type服务端和producer端进行设置。
4.1.1.服务端配置
为指定的topic设置压缩类型,可选值有uncompressed、zstd、lz4、snappy、gzip、producer六种,默认值为producer,表示使用producer端的配置。当配置为uncompressed时,不会对写入磁盘的数据进行压缩。
4.1.2.topic配置
可以为topic设置compression.type参数,含义与服务端配置一致。
4.1.3.producer端配置
producer端设置了此参数后,生产的数据都会在压缩后发送给Broker,可选值有none、gzip、snappy、lz4、zstd共五种,默认none,表示不压缩。
需要注意的是,压缩是对整体批量数据的压缩,批量的大小会影响到压缩的比率,一般来说,更大的批量意味着更高的压缩比率。