容器里起了 24 个消费线程,kafka-consumer-groups 显示只有 6 个分区被分配,另外 18 个线程 poll 一直返回空集合,CPU 却多了 15%。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
kafka-consumer-groups.sh --bootstrap-server kafka:9092 \
--describe --group order-consumer | awk '{print $2,$4}'
kafka-topics.sh --bootstrap-server kafka:9092 \
--describe --topic order-event | grep PartitionCount
一个分区同一时刻只能被组内一个消费者消费,线程数超过分区数,多出来的线程拿不到分配结果。空转的 poll 仍按 fetch.max.wait.ms 反复发请求。这一点先确认清楚,后面就不用反复试。
碰到「Kafka 消费线程空转」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。
备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。
具体做法是,把 concurrency 调到不超过分区数 先设成 6;确实要更高并行就扩分区 再按新分区数调线程;用 describe 确认每个线程都有 assignment 别只看进程数;线程空闲时把 fetch.max.wait.ms 从 500 调到 2000 减少空请求。
改完照着核一遍,24 个线程降到 6 个 每个都分到分区 CPU 回落到原来的水平。
