Kafka 消息积压:从定位原因到扩容的排查手册
消息队列积压是最常见的线上告警之一:生产者还在不停地写,消费者却越落越远,Lag 曲线一路向上。积压本身不可怕,可怕的是不知道它卡在哪一环。本文按“先看指标、再定原因、最后动手”的顺序,讲一套可直接照着做的排查流程。
一、先确认:到底积压了多少,在哪个环节
打开 Kafka 的监控,先看三个数:
- Lag(消费滞后量):Log End Offset - Consumer Offset,按 Topic/分区看,不要只看总量——总量正常也可能有个别分区严重滞后。
- 生产速率 vs 消费速率:用 kafka-consumer-groups --describe 或监控面板对比近 15 分钟的入队速率与出队速率。如果入队速率突然翻倍,问题在上游;如果消费速率掉下来,问题在消费端。
- 分区分布:检查 Lag 是否集中在某几个分区。集中在个别分区,往往是 Key 分布不均或某个消费者实例挂了;全部分区均匀上涨,往往是整体消费能力不足或下游变慢。
一个实用命令:
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group order-consumer
重点看 LAG 列和 CONSUMER-ID 列:CONSUMER-ID 为空的分区就是没人消费的分区。
二、常见原因与定位方法
- 消费者实例挂了或 Rebalance 频繁
如果某个分区的 CONSUMER-ID 为空,先查消费者进程是否存活、日志里有没有 CommitFailedException 或 Rebalance。Rebalance 频繁的典型诱因是消费处理耗时超过 max.poll.interval.ms(默认 5 分钟),消费者被踢出组,触发再平衡,再平衡期间分区无人消费,Lag 继续涨,形成恶性循环。
定位方法:查消费端日志的 Rebalance 记录;看单条消息处理耗时 P99 是否接近或超过 max.poll.interval.ms。处理办法是调大该参数、缩短单次 poll 的处理量(减小 max.poll.records)、或把耗时操作异步化。
- 下游变慢:数据库、外部接口拖住了消费
消费者的瓶颈常常不在 Kafka 本身,而在它调用的下游。逐条同步写库、调外部 HTTP 接口、每次消费都查一次缓存穿透到库,都是典型慢点。
定位方法:给消费处理加耗时埋点,分段统计“拉取耗时 / 业务处理耗时 / 提交耗时”,哪段高就查哪段。处理办法:批量写入代替逐条写入、加本地缓存、对下游调用加超时和熔断,避免一个慢接口拖垮整个消费线程池。
- 生产者突发流量:消费能力本身不够
大促、批量任务、重试风暴都会让入队速率在短时间内翻几倍,而消费端的线程数、分区数是固定的,吞吐存在上限。
定位方法:对比积压开始时刻的入队速率曲线与历史基线;确认是否是突发而非持续增长。处理办法:先扩消费者实例数(前提是分区数足够——消费者数超过分区数没有意义),再考虑增加分区数(新分区只对新消息生效,旧分区积压仍需老消费者消化);长期方案是按业务做流量削峰与限流。
- Key 分布不均:个别分区被“撑爆”
按用户 ID、订单号做 Key 时,如果某个大客户的量占了绝大多数,对应分区会持续高 Lag,而其他分区很闲。
定位方法:按分区看 Lag 和入队速率,确认是否集中。处理办法:对热点 Key 做打散(如 Key 后缀加随机因子、按业务拆 Topic),或给热点分区单独配消费组。
- 消费逻辑 Bug:死循环、重试不收敛
消费失败后无限重试同一条消息(不设重试上限、不进死信队列),会让该分区彻底卡住,后面的消息全部排队。
定位方法:看消费日志是否在同一 Offset 反复报错;看 CURRENT-OFFSET 是否长时间不动。处理办法:重试设上限(例如 3 次),超限进死信队列(DLQ)人工处理;消费逻辑必须保证幂等,避免重试造成重复写库。
三、应急处理:积压已经很大时先止血
- 先扩消费能力:加消费者实例、调大 fetch.max.bytes 和 max.poll.records、临时调大消费线程池,是最快见效的办法。
- 临时跳过非关键消息:确认积压消息可丢弃或可事后补(如埋点日志类),可临时把 Offset 重置到最新(–reset-offsets --to-latest),先恢复实时性再补数据;核心业务消息绝不能这样做。
- 限流生产者:突发流量未消退时,对生产端限流、暂停非核心生产者,避免 Lag 越积越深。
- 监控别只看总量:按分区、按消费组设 Lag 告警阈值,单个分区 Lag 超阈值就告警,别等总量报警才发现。
四、事后复盘清单
- 消费端有没有做耗时埋点?没有的话下次还是盲人摸象。
- 重试有没有上限和死信队列?没有的话迟早被一条脏消息卡住。
- 分区数够不够?消费者数是否已等于分区数?不够的话提前扩分区。
- 下游有没有超时、熔断、批量写?同步逐条写库是积压的温床。
- 告警阈值是否按分区设?总量告警发现问题时往往已经晚了。
结语
排查 Kafka 积压就三句话:先看 Lag 分布定范围,再看速率对比定方向,最后分段埋点定根因。多数积压不是 Kafka 的问题,而是消费端处理能力、下游依赖或流量突增的问题。把埋点、重试上限、死信队列、分区分组告警这四件套做扎实,下次告警响起时,你就不用再凭感觉猜了。
- 点赞
- 收藏
- 关注作者
评论(0)