作者:等等在学习
链接:https://www.zhihu.com/question/528641357/answer/2536382193
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
前言
我们在写sql的时候经常发现读取数据不多,但是代码运行时间异常长的情况,这通常是发生了数据倾斜现象。数据倾斜现象本质上是因为数据中的key分布不均匀,大量的数据集中到了一台或者几台机器上计算,这些数据的计算速度远远低于平均计算速度,从而拉慢了整个计算过程速度。
本文将介绍如何通过日志分析,判断数据中的哪个key分布不均,从而导致了数据倾斜问题。
任务是否发生了倾斜
hive判断
hive运行日志
当我们在hive作业运行日志中,发现reduce任务长时间卡在99%时,即可判断任务发生了数据倾斜。
其原理是这样的:
分布式处理逻辑
分布式处理实际上是按数据中的key将数据分摊到多个机器上运行,假如出现了数据倾斜问题,如上图。可以想象,当1min过去后,我们的任务完成率只有67%,并且在接下来的9min时间内,任务完成率将持续卡在67%上。因此,当我们发现任务完成率长时间卡在99%时,即判断发生了数据倾斜。
spark判断
spark UI界面
我们进入spark UI界面,发现第2个job的运行时间长达1.8h,而其他job运行时间不超过2min,判断该job有可能发生数据倾斜。
进一步分析job,可以看到该job只存在一个stage(9)
stage界面
进一步分析stage,发现不管是duration还是shuffle的数据量,max和median都有明显的差距,可以肯定是job(5)的stage(9)发生倾斜。
寻找倾斜key
当我们发现任务倾斜了,自然而然就希望找到倾斜的key,从而修复数据倾斜的现象。当然,这部分我也会分为hive和spark两个部分进行介绍。
hive识别
step1:确认是哪个Job出现了严重的倾斜问题
hive运行日志
通过搜索tracking的方式,我们发现第3个job的reduce任务一直卡在99%上,判断其发生了倾斜问题。
step2:进入相应的Tracking URL,查看SUCCESSFUL REDUCE
很明显,其他的taske都在2min之内完成,只有000000_1需要耗费1个多小时的时间完成。
另外注意,这里面需要排除一种特殊情况。有时候,某个task执行的节点可能有问题,导致任务跑的特别慢。这个时候,mapreduce的推测执行,会重启一个任务。如果新的任务在很短时间内能完成,通常则是由于task执行节点问题导致的个别task慢。如果推测执行后的task执行任务也特别慢,那更能说明该task可能会有倾斜问题。
step3:进入log日志,查看syslog
hive的syslog日志
可以从log日志中看到,该job仅仅运行了file和group操作后,就将数据写入至hive表中。那么,我们可以确认的是,该job运行的是最后一个group by操作。
step4:对照运行sql
运行sql
我们可以看到,在group by阶段,count(distinct)的出现造成了数据倾斜。
spark识别
step1:找到该任务运行的stage
spark UI界面
我们看到该运行任务,可以发现第2个job运行时间长达1.8h,远大于其他job,可以判定倾斜发生在job(5)。
step2:点击SQL,查看Details for Query
Details for Query
可以从sort time total/peak memory total/spill size total看出来,左表的package_name分布不均匀,此时可以通过查看scan parquet了解具体是哪张表。
step3:对照运行sql
运行sql代码
查询package_name的分布情况
select package_name,count(1) as cnt from test1 where date=20220619 group by package_name order by cnt desc limit 10;
package_name的分布验证了我们的猜想,test1.package_name造成了数据倾斜