数据倾斜就是在分布式计算的时候,数据的分散度不够,导致大量的数据集中到一台或几台机器上计算,导致整个任务的计算速度及效率大大下降。本文主要分析出现数据倾斜的原因及解决方案。
数据倾斜的原理及体现
在MapReduce的shuffle阶段,将相同的key拉取到一个Reduce上计算,若某一种key的数据量远远大于其他的key的数据量,造成某一个Reduce Task计算量过大,计算耗时较长,导致整个任务的计算速度及效率大大下降。因此数据倾斜一般有两种表现:① 大部分Reduce Task执行完成特别快,某一个Reduce Task执行特别慢,耗时长;② 某一个Reduce Task出现OOM,内存溢出,任务失败。
解决方案
MapReduce中的数据倾斜解决方案
- 自定义
combiner类。在map shuffle阶段对数据压缩,相当于做一次Reduce,相同的key先进行聚合运算。从而减少流向Reduce端的文件数量和数据量。 - 分析导致数据倾斜的
key,在Map阶段将造成倾斜的key分成多组,例如aaa这个key,map时随机在aaa后面加上 1,2,3,4 这四个数字之一,把key先分成四组,先进行一次运算,之后再恢复 key 进行最终运算。
Hive 中数据倾斜的解决方案
- 参数调优
1
2set hive.map.aggr = true;
set hive.groupby.skewindata = true;
hive.map.aggr = true;在Map中做部分聚集操作,效率更高且需要更多的内存。hive.groupby.skewindata = true;数据倾斜时会进行负载均衡,当选项设定为true,生成的查询计划会有两个MapJob。第一个MRJob中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的GroupBy Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MRJob再根据预处理的数据结果按照GroupBy Key分布到Reduce中(这个过程可以保证相同的GroupBy Key被分布到同一个Reduce中),最后完成最终的聚合操作。
join操作中,驱动表的选取
1) 选取key分布均匀的表作为join的驱动表;做好列裁剪和过滤操作,以到达两个表join时,数据量相对变小的效果。
2) 大小表join时,使用map join时,让小维度表现进入内存。
3) 大表join大表时,把空值的key变成一个字符串加随机数,把倾斜的数据分布到不同的Reduce上,由于null值关联不上,处理后并不理解结果。- 能先进行
gourp by操作的先进行gourp by操作,把key先进行一次Reduce之后再进行count或者distinct count操作。