知识总结帖,来源:https://www.cnblogs.com/HuZihu/p/12742931.html
什么是数据倾斜(Data Skew)?
数据倾斜是指在原本应该并行处理的数据集中,某一部分的数据显著多于其它部分,从而使得该部分数据的处理速度成为整个数据集处理的瓶颈。
假设数据分布不均匀,某个key对应几十万条数据,其他key对应几百条或几十条数据,那么在处理数据的时候,大量相同的key会被分配(partition)到同一个分区里,造成"一个人累死,其他人闲死“的情况,具体表现在:有些任务很快就处理完了,而有些任务则迟迟未能处理完,导致整体任务最终耗时过长甚至是无法完成。
数据倾斜分为map端倾斜和reduce端倾斜。
要真正了解数据倾斜,需要知道MapReduce的工作原理。(以下摘自:https://www.zhihu.com/question/27593027)
举个 word count 的入门例子,它的map 阶段就是形成 (“aaa”,1)的形式,然后在reduce 阶段进行 value 相加,得出 “aaa” 出现的次数。若进行 word count 的文本有100G,其中 80G 全部是 “aaa” ,剩下 20G 是其余单词,那就会形成 80G 的数据量交给同一个 reduce 进行相加,其余 20G 根据分配到不同 reduce 进行相加的情况。如此就造成了数据倾斜,临床反应就是 reduce 跑到 99%,然后一直在原地等着那80G 的reduce 跑完。
数据倾斜产生的原因:
1,map端:输入文件的大小不均匀
2,reduce端:key分布不均匀,导致partition不均匀
Map 端倾斜解决办法
map 端倾斜通常是由于文件大小不均匀导致的,比如有个表按天分partition,某些促销日数据很多。
解决办法是合并小文件。
set hive.merge.mapfiles=true;
set hive.merge.per.task = 256*1000*1000;
set mapred.max.split.size = 256000000;
set mapred.min.split.size.per.node = 256000000;
Set mapred.min.split.size.per.rack=256000000;
set hive.input.format =org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
Reduce 端倾斜解决办法
当group by分组的维度过少,每个维度的值过多时:调优参数
(1)设置在map阶段做部分聚合操作
hive.map.aggr=true
效率更高但需要更多的内存。
(2)设置数据倾斜时负载均衡
hive.groupby.skewindata=true
当选项设定为true,生成的查询计划会有两个MRJob。第一个MRJob 中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的GroupBy Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MRJob再根据预处理的数据结果按照GroupBy Key分布到Reduce中(这个过程可以保证相同的GroupBy Key被分布到同一个Reduce中),最后完成最终的聚合操作。
起至关作用的是第(2)项,它分为了两个mapreduce,第一个在shuffle过程中partition时随机给key打标记,使其分布在不同的reduce上计算,但不能完成全部运算,所以需要第二次mapreduce整合回归正常的shuffle,由于数据分布不均问题在第一次时得到改善,所以基本解决数据倾斜问题。
设置参数:
set hive.optimize.skewjoin=true;
set hive.skewjoin.key=100000;
map reduce 运行时也可以通过指定RangePartitioner来代替HashPartitioner让数据均匀分布。
https://www.cnblogs.com/tongxupeng/p/10435976.html
参考文章
https://www.cnblogs.com/HuZihu/p/12742931.html
https://www.cnblogs.com/liqiu/p/4878078.html
https://blog.csdn.net/hellojoy/article/details/82931827
https://www.jianshu.com/p/daa4e7c86925