首页/数据/数据工程与 ETL 速查/生产者批处理 linger.ms 与 batch.size
Kafka64 条

生产者批处理 linger.ms 与 batch.size

生产者把小消息合并成批发送以提升吞吐:linger.ms 控制等待时间、batch.size 控制单批字节上限;等待越久批次越大,延迟也越高。

生产者批量发送

Kafka 生产者不会一条一条发消息,而是把发往同一分区的记录先在内存里攒成批,再一次性发给 broker。linger.ms 决定「攒多久」,batch.size 决定「攒多大」;两者的组合就是吞吐与延迟之间的旋钮。等待时间越长、批次越大,网络往返与压缩摊薄的收益越高,代价是单条消息的端到端延迟上升。

基本信息

linger.ms批次等待时间,默认 0(有记录即发)
batch.size单分区单批字节数上限,默认 16KB
buffer.memory生产者总缓冲,默认 32MB,写满会阻塞或抛异常
compression.type批次压缩算法,lz4、zstd 在吞吐与 CPU 间取舍
max.request.size单次请求上限,默认 1MB,需与 broker 侧匹配

吞吐优先配置示例

吞吐优先配置示例
linger.ms=20
batch.size=65536
compression.type=lz4
buffer.memory=67108864
acks=1                                  # 对可靠性要求不高的日志链路可放宽
max.in.flight.requests.per.connection=5 # 配合幂等时上限为 5

典型使用场景

  • 日志与埋点链路:追求吞吐、能接受几十毫秒延迟,可以把 linger.ms 调到 20 以上
  • 实时风控等低延迟场景:保持 linger.ms=0,靠增大 batch.size 在高负载时自然成批
  • 跨机房或跨云传输:带宽紧张时开压缩,用 CPU 换流量
  • 批量导入历史数据:临时把缓冲和批次都放大,缩短整批数据的写入时间
  • 排查发送变慢:先看 buffer.memory 是否偏小,写入速度快于网络发送速度时缓冲区会先满

参数调优对照

现象含义调整方向
吞吐上不去、CPU 不高批次太小,请求次数过多适当调大 linger.ms 与 batch.size
端到端延迟明显上升等待成批的时间计入延迟下调 linger.ms,或按链路分级配置
报 Failed to allocate memory缓冲区写满,send 阻塞超时加大 buffer.memory 或降速
单条 RecordTooLargeException超过 produce 请求或 broker 上限检查 max.request.size 与 message.max.bytes
压缩后 CPU 飙升压缩算法太重或批次太小换用 lz4,或增大批次摊薄压缩成本
缓冲区不足时 send() 会阻塞到 max.block.ms 超时,异常信息是 TimeoutException: Failed to allocate memory;这条报错常被误判成网络问题。
批次按分区攒:目标 topic 分区数越多,同样的 batch.size 下总内存占用越大,buffer.memory 要按「分区数 × batch.size」量级估算。

易错点

  • linger.ms 调大会让端到端延迟上升,实时链路要权衡后再改
  • 单条消息超过 max.request.size(或 broker 的 message.max.bytes)会直接发送失败
  • 只调 batch.size 不调 linger.ms,低流量时批次仍然攒不大,吞吐改善有限
  • 开压缩却没核对 broker 与消费端版本,旧客户端可能无法解压新算法
  • 把 acks 降到 0 换吞吐,节点故障时会静默丢消息且无从感知

数据来源与参考

  • Apache Kafka 官方文档:Producer Configs 与 Design(Batching)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌