生产端没有设置 key,十个分区里有九个长期空置,只有一个分区承担 87% 的写入,broker 磁盘和网络都不均衡。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
# producer.properties partitioner.class=org.apache.kafka.clients.producer.RoundRobinPartitioner batch.size=16384 kafka-run-class.sh kafka.tools.GetOffsetShell \ --bootstrap-server kafka:9092 --topic order-event
key 为 null 时分区器按批次选一个分区并尽量复用,早期版本是轮询,2.4 之后改成粘性,一个批次内全压同一分区。批越大偏得越明显。这一点先确认清楚,后面就不用反复试。
「Kafka key 为空」这类改动最怕改一半,回滚脚本先准备好,再动生产。临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。
动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。
具体做法是,需要均匀分布就给 key 传业务主键;确实不需要顺序的升级到 3.3 以上 用内置的均匀粘性分区器;调小 batch.size 让批次更碎 分布更散;用 GetOffsetShell 对比各分区消息量。
改完照着核一遍,十个分区的 offset 增量差距缩小到 10% 以内 单台 broker 不再偏载。
