华为云 DMS 分布式消息队列 Kafka 消息堆积与消费位点重置实战
华为云 DMS 分布式消息队列 Kafka 消息堆积与消费位点重置实战
上周一上线一个新的订单聚合服务,上线后观察窗内一切正常。但周一晚高峰刚开始,Kafka 的消费延迟曲线突然从几百毫秒直接拉到了十几分钟,堆积量一路涨到八百万条。更诡异的是,应用的消费线程并没有报错,也没有触发任何告警,只是"变慢了"。
事后看监控才发现,问题的源头其实在上线前一天。为了赶进度,我们把一个原本放在同步链路里的"积分试算"逻辑挪进了 Kafka,消费组里多了一个下游实例,而这个实例的消费者配置里 `max.poll.records` 默认是 500,客户端又启用了自动提交位点。一条消息在业务处理里要调用三次外部接口,单条耗时接近 60 毫秒,500 条串行下来就是 30 秒——而消费组的心跳和位点提交间隔远小于这个时间,rebalance 就开始反复触发。
这次排查让我彻底理解了 DMS Kafka 里"消息堆积"和"消费停滞"的区别,下面把完整过程和最终的修复方案整理出来。
一、先分清堆积的三种成因
排查的第一步不是看监控曲线,而是先分清是生产端堆积还是消费端停滞。
**生产端突发堆积**的特征是:单个分区 Lag 上涨,但每个消费者的处理速率正常。这种情况通常是大促、批量导入或者上游任务补偿造成的,核心动作是横向扩消费者。判断依据是所有分区的 Lag 是否呈现均匀上涨——如果均匀,说明消费能力没问题,只是瞬时流量超过了设计容量。
**单分区倾斜堆积**更隐蔽。我们第一次遇到时,监控上只有 3 个分区 Lag 高,剩下几个几乎为 0。原因是上游的业务主键在发送端没有做分区键设计,走了随机分区,于是写热点全压在少数分区上。这类问题的正确解法不是扩容,而是修分区键:DMS Kafka 支持自定义分区策略,改成按业务主键哈希之后,Lag 会立刻被摊平。
**消费端停滞**就是这次遇到的:所有分区的 Lag 同步上涨,且上涨速率超过消费速率,但消费者进程还活着。这种情况下监控上的"消费者数量"是正常的,很容易被误判为"流量太大了"。判断依据是看单条消息的处理耗时和 `max.poll.interval.ms` 的关系——只要单批处理时间超过了最大轮询间隔,rebalance 就会开始,rebalance 又会导致位点回退、重复消费,进一步拖慢处理,形成正反馈。
二、位点重置是止损手段,不是解决方案
止损的时候我们用到了位点重置。DMS Kafka 控制台提供了按时间戳或按 Offset 的位点重置入口,指定一个新起点后,消费者会从新的位置开始消费。
但这里有个坑必须提醒:位点重置会让新位置到当前位点之间的消息被重新消费一遍,如果下游没有做幂等,就会产生重复数据。我们的下游是写一张积分流水表,天然带业务主键幂等,所以才能放心重置。重置前必须先确认下游的幂等能力,这是使用这个功能的前提。
我们的实际处置分三步:第一步,临时把消费组的 `max.poll.records` 从 500 调到 20,直接把单批处理时间压到 3 秒以内;第二步,重置位点到堆积开始前 10 分钟,让增量数据以可控速度回放;第三步,同步重启消费者,把自动提交改成手动提交,每批处理完再显式提交位点。8 分钟后 Lag 从八百万降到正常区间,业务侧没有感知到任何异常。
三、把"能自愈"的能力固化到代码里
这次故障之后,我们对所有使用 DMS Kafka 的服务做了一次统一整改,重点是三条。
一是把 `max.poll.records` 从依赖默认值改成显式配置,并保证单批处理时间不超过最大轮询间隔的三分之一。这条后来被写进了我们的上线检查清单,任何新增消费者都必须在 MR 里贴出这两项配置。
二是关闭位点自动提交,统一改为手动提交,并且把位点提交和业务事务解耦——业务写库成功后再提交位点,宁可重复消费也不丢消息。
三是给每个消费组加了两个监控项:Lag 绝对值和 Lag 增长率。绝对值告诉你"积了多少",增长率告诉你"还在不在恶化"。我们现在的告警规则是"Lag 增长率连续 5 分钟大于阈值"而不是"Lag 大于某个数",因为积压一千条但还在涨,比积压十万条但正在下降严重得多。
四、回到日常:把排查动作固化
最后留一个小工具:我们写了一个排查脚本,输入是消费组名和 Topic,输出依次是分区级 Lag 分布、每批处理的平均耗时、以及从最后一次位点提交到现在的时间间隔。三个数据一摆出来,结论基本就出来了——Lag 不均匀就是分区键问题,全均匀且增速超过消费速率就是容量不足,全均匀且增速低于消费速率但绝对值一直不降,那就是消费停滞,去查批处理耗时和轮询间隔。
Kafka 的排查思路其实和数据库很像:先分清是"进多了"还是"出少了",再看分布是均匀还是不均匀。工具用对了,大部分问题在十分钟内就能定位到根因,而不是靠猜。
- 点赞
- 收藏
- 关注作者
评论(0)