# 如何判断发生数据倾斜
数据倾斜多发生在Shuffle阶段。Mapper按InputSplit切分，一般相对均匀。数据倾斜指表中数据分布不均，Shuffle后分配到不同Task（运行在Executor上的工作进程）的数据量差异巨大。数据不均匀时，有的Task很快就计算完成，有的Task却需要运行很长时间。
作业运行表现为：作业执行进度长时间停留在99%，作业执行感觉被卡住；Spark UI上某个Stage的大部分Task已完成，仅剩少数Task长时间运行。
#### 判断步骤
在History Server中通过WebUI判断数据倾斜，具体步骤如下：
1. 在Stages页签中选择运行时间较长的Stage。
2. 在Stage中查看Show Additional Metrics表格中的Duration行观察执行时间是否存在倾斜：比较Max列（执行时间最长的任务）与Median列（执行时间中位数）差距有多大。查看表格中其他指标，观察资源占用是否存在倾斜：比如内存（Peak Execution Memory）、磁盘（Input/Output Size）。
3. 根据Stage编号，可以在DAG图中定位到Stage对应的算子，进而定位导致数据倾斜的SQL代码片段。
#### 使用示例
通过History Server或YARN/集群调度器入口找到对应作业的**Spark UI** 链接。进入Spark UI，在**Stages**页签按Duration降序，快速锁定耗时最长的Stage。
例如某Stage的Task统计摘要为：
```
Duration: min 6s, 25th % 8s, median 13s, 75th % 18s, max 26m40s 
Shuffle Read Size: min 2MB, median 15MB, max 12GB
```
表示该Stage下所有Task的最小运行时长6s，中位数13s，最大运行时长26min40s；Shuffle Read同样存在极端长尾。
在**Tasks** 表中按Duration降序，可看到少数几个运行时间显著偏长的Task。切换到**Event Timeline**视图，可直观看到大部分Task很快结束，而个别Task拖成一条很长的"长尾"横条。
对比这些长尾Task与正常Task的Shuffle Read Size / Records：若长尾Task的读取量是平均值的数十倍甚至更高，即可确认为数据倾斜（而非算子本身耗时）。单击该Task查看其stderr/stdout或对应Executor日志，结合Stage DAG中的Shuffle Read上游算子，定位到导致倾斜的key（如 new_uri_path_structure、cookie_x5check_userid、cookie_userid），从而定位到数据倾斜的SQL片段。
