早上七点出头,团队群被一条调度告警刷屏了。平时稳定20分钟跑完的dws_flow_channel_uv_di任务,今天跑了一个多小时还挂在YARN上,最终以1小时21分收场。这个任务是数仓里再普通不过的渠道UV日报,源表是每天的行为明细,逻辑就是GROUP BY channel加COUNT(DISTINCT user_id)。看到任务卡住的那一刻,我第一反应是"是不是上游数据量暴涨了?",但打开YARN页面看完Task分布,心里基本就有数了——这是典型的数据倾斜。这篇文章就还原一下当时从报警到定位、再从修复到复盘的全过程,希望能给同样被Hive数据倾斜折磨过的朋友一点参考。
1. 突发变慢:从20分钟到81分钟的报警现场
1.1 单量暴涨?先做一轮"外部因素"排除
任务跑得慢,最忌讳的就是上来就喊"数据倾斜",因为资源抢占、上游延迟、甚至队列配置变更都可能造成同样的表象。我当时的排查顺序是这样的:
- 先和上游同步任务的负责人确认,昨天到今天
dwd_flow_event_detail的分区数据量基本持平,没有出现类似翻倍式增长。 - 再看YARN队列,集群里同时段就只有三四个常规任务,资源剩余充足,不存在被大任务挤占的问题。
- 确认最近一周没人动过Hive的执行参数、队列容量调度配置。
- 最后看了下HiveServer2的锁状态,没有出现长时间
LOCK_WAIT。
这一轮走完,外部因素基本可以排除。任务变慢的嫌疑全部落在了SQL本身和执行过程上。
1.2 把嫌疑锁定在任务内部执行环节
排除了外部因素之后,比较常见的内部原因也无非是几种:执行计划发生改变、Map阶段小文件暴涨导致启动任务过多、某个Task反复重试,或者某个Task承担了远超预期的数据量。
我当时的主要判断依据是阶段耗时。在YARN和调度平台的监控页面上,能看到每个阶段的大致耗时区间。如果Map阶段耗时和平时差不多,说明数据读入、解析、过滤都没问题;如果Reduce阶段出现异常的长尾,那就要往"同一个key的数据全部被路由到了同一个Reducer"这个方向去想。后来证实,这个思路是对的——Map阶段没有异常,真正的问题全部集中在Reduce阶段。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 缩小包围圈:YARN长尾与Shuffle硬指标坐实倾斜
2.1 Reduce长尾:并行任务里那几颗"钉子"
从YARN Application页面进入Tasks标签页,按Task类型过滤后,现象非常直观:96个Reduce Task里,93个都在10到15分钟内跑完了,唯独剩下3个Task,状态一直卡在RUNNING,耗时一路冲到80分钟附近才结束。
这是数据倾斜最具标志性的画面——大量并行任务已经"收工",少数几个Reduce Task成了"钉子户"。分布式计算有个最朴素的规则:整个作业的完成时间取决于最后一个完成的Task,而不是平均耗时。当这3个Reducer还在处理海量数据的时候,哪怕其他93个Reducer全部空闲,整个作业也只能干等。
2.2 三个Task级Counter:Shuffle字节数、Spill次数、GC时间
只看长尾还不够,我得拿到更硬的证据去确认"到底是不是数据分配不均"。于是进到YARN History Server,逐个点开这几个最慢Task的Counter,和正常Task做了个对比:
| 指标 | 最慢Task(3个) | 正常Task(93个) |
|---|---|---|
| Task完成耗时 | 约75- |
