如何判断发生数据倾斜
数据倾斜多发生在Shuffle阶段。Mapper按InputSplit切分,一般相对均匀。数据倾斜指表中数据分布不均,Shuffle后分配到不同Task(运行在Executor上的工作进程)的数据量差异巨大。数据不均匀时,有的Task很快就计算完成,有的Task却需要运行很长时间。
作业运行表现为:作业执行进度长时间停留在99%,作业执行感觉被卡住;Spark UI上某个Stage的大部分Task已完成,仅剩少数Task长时间运行。
判断步骤
在History Server中通过WebUI判断数据倾斜,具体步骤如下:
- 在Stages页签中选择运行时间较长的Stage。
- 在Stage中查看Show Additional Metrics表格中的Duration行观察执行时间是否存在倾斜:比较Max列(执行时间最长的任务)与Median列(执行时间中位数)差距有多大。查看表格中其他指标,观察资源占用是否存在倾斜:比如内存(Peak Execution Memory)、磁盘(Input/Output Size)。
- 根据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片段。