Kafka 消息积压排查实战:从消费组到分区的五步流程
背景
某天凌晨,订单系统的核心 Topic 消费延迟告警触发:消费组 lag 突然从 0 涨到 120 万条,订单状态同步延迟超过 15 分钟,下游仓储、财务系统陆续出现超时。本文记录从发现告警到彻底消除积压的完整排查过程。
先讲一个核心概念:lag = 分区最新位移(log-end-offset)- 消费组已提交位移(committed offset)。lag 上涨只有两种可能:生产太快,或者消费太慢。排查的思路,就是沿着这条链路一层层缩小范围。
第一步:确认积压是全局的,还是个别分区的
# 查看消费组整体 lag 与各分区 lag
kafka-consumer-groups.sh --bootstrap-server ${BROKER} \
--describe --group order-consumer-group
# 查看 Topic 分区数与副本分布
kafka-topics.sh --bootstrap-server ${BROKER} --describe --topic order-events
如果 lag 集中在个别分区,优先怀疑分区倾斜或个别消费者异常;如果全部分区均匀上涨,优先怀疑消费能力不足或下游依赖变慢。那次故障里 12 个分区的 lag 都在涨,说明不是个别分区的问题。
第二步:检查消费者是否存活、是否频繁重平衡
# 观察消费组状态、成员与分区分配情况
kafka-consumer-groups.sh --bootstrap-server ${BROKER} \
--describe --group order-consumer-group --state
# 从消费者日志里找重平衡的痕迹
grep -i "rebalance\|Revoking\|JoinGroup" /var/log/order-consumer/app.log | tail -n 50
那次故障中,消费组状态在 PreparingRebalance 与 Stable 之间反复横跳:原因是 session.timeout.ms 设得过小,一次 Young GC 停顿超过超时后成员被踢出组,触发一轮轮重平衡,消费几乎停滞。把 session.timeout.ms 从 10 秒调到 45 秒、max.poll.interval.ms 调到 5 分钟后,重平衡停了下来。
第三步:定位消费变慢的具体环节
# 抓消费耗时:处理单条消息的 P99
grep "process-cost" /var/log/order-consumer/app.log | awk '{print $NF}' | sort -n | tail -n 5
# 抓下游调用耗时:下游耗时同样取 P99,对比前后变化
grep "downstream-cost" /var/log/order-consumer/app.log | awk '{print $NF}' | sort -n | tail -n 5
本次故障的另一半原因是下游订单库的一条 SQL 走了全表扫描,单条处理从 5ms 涨到 800ms。抓到慢调用后,先给这条 SQL 补上索引,把 P99 拉回 10ms 以内,消费速度立即恢复。
第四步:临时扩容,把积压先“追”回来
# 临时把消费实例数翻倍(注意:实例数不要超过分区数)
kubectl scale deployment order-consumer --replicas=12
# 实时观察 lag 回落速度
watch -n 5 "kafka-consumer-groups.sh --bootstrap-server ${BROKER} --describe --group order-consumer-group | awk '{print \$5}'"
注意两个约束:消费实例数超过分区数时,多余实例分不到分区,白白占用资源;分区数不够时,先评估扩分区(会改变分区路由,需要谨慎)再扩容。
第五步:设置告警与兜底,防止复发
# 周期巡检脚本示例:lag 超过阈值即告警
kafka-consumer-groups.sh --bootstrap-server ${BROKER} \
--describe --group order-consumer-group \
| awk 'NR>1 && $5>100000 {print "LAG告警:", $1, $5}'
同时做三件事:消费组 lag 告警阈值设为 10 万条并接入值班群;消费端加处理超时熔断,失败消息进死信队列(DLQ)而不是阻塞消费;每月做一次消费压测,验证单实例吞吐与扩容上限。
总结
Kafka 积压的排查顺序可以固定下来:先看 lag 分布,再看重平衡,再看消费耗时与下游依赖,最后扩容追赶并补告警兜底。本次故障的根因是下游慢 SQL 叠加频繁重平衡,修复后 lag 在 20 分钟内从 120 万归零。记住两个数字:消费实例数不超过分区数,lag 告警阈值按业务可接受的延迟倒推,不要等到下游超时才发现问题。
- 点赞
- 收藏
- 关注作者
评论(0)