「埃尔法哥哥」Spark 数据倾斜的 8 大实用方法,解决( 五 )


Hadoop中的数据倾斜
Hadoop中直接贴近用户使用的是Mapreduce程序和Hive程序 , 虽说Hive最后也是用MR来执行(至少目前Hive内存计算并不普及) , 但是毕竟写的内容逻辑区别很大 , 一个是程序 , 一个是Sql , 因此这里稍作区分 。
Hadoop中的数据倾斜主要表现在ruduce阶段卡在99.99% , 一直99.99%不能结束 。
这里如果详细的看日志或者和监控界面的话会发现:
有一个多几个reduce卡住
各种container报错OOM
读写的数据量极大 , 至少远远超过其它正常的reduce
伴随着数据倾斜 , 会出现任务被kill等各种诡异的表现 。
经验:
Hive的数据倾斜 , 一般都发生在Sql中Group和On上 , 而且和数据逻辑绑定比较深 。
优化方法:
这里列出来一些方法和思路 , 具体的参数和用法在官网看就行了 。
mapjoin方式
countdistinct的操作 , 先转成group , 再count
参数调优
sethive.map.aggr=truesethive.groupby.skewindata=https://pcff.toutiao.jxnews.com.cn/p/20200505/true
leftsemijion的使用
设置map端输出、中间结果压缩 。 (不完全是解决数据倾斜的问题 , 但是减少了IO读写和网络传输 , 能提高很多效率)
说明:
hive.map.aggr=true:在map中会做部分聚集操作 , 效率更高但需要更多的内存 。
hive.groupby.skewindata=https://pcff.toutiao.jxnews.com.cn/p/20200505/true:数据倾斜时负载均衡 , 当选项设定为true , 生成的查询计划会有两个MRJob 。 第一个MRJob中 , Map的输出结果集合会随机分布到Reduce中 , 每个Reduce做部分聚合操作 , 并输出结果 , 这样处理的结果是相同的GroupByKey有可能被分发到不同的Reduce中 , 从而达到负载均衡的目的;第二个MRJob再根据预处理的数据结果按照GroupByKey分布到Reduce中(这个过程可以保证相同的GroupByKey被分布到同一个Reduce中) , 最后完成最终的聚合操作 。