MapReduce中数据倾斜的原因及解决方案

    数据倾斜就是在分布式计算的时候,数据的分散度不够,导致大量的数据集中到一台或几台机器上计算,导致整个任务的计算速度及效率大大下降。本文主要分析出现数据倾斜的原因及解决方案。

数据倾斜的原理及体现

    在MapReduce的shuffle阶段,将相同的key拉取到一个Reduce上计算,若某一种key的数据量远远大于其他的key的数据量,造成某一个Reduce Task计算量过大,计算耗时较长,导致整个任务的计算速度及效率大大下降。因此数据倾斜一般有两种表现:① 大部分Reduce Task执行完成特别快,某一个Reduce Task执行特别慢,耗时长;② 某一个Reduce Task出现OOM,内存溢出,任务失败。

解决方案

MapReduce中的数据倾斜解决方案
  1. 自定义combiner类。在map shuffle阶段对数据压缩,相当于做一次Reduce,相同的key先进行聚合运算。从而减少流向Reduce端的文件数量和数据量。
  2. 分析导致数据倾斜的key,在Map阶段将造成倾斜的key分成多组,例如aaa 这个 keymap 时随机在aaa 后面加上 1,2,3,4 这四个数字之一,把key 先分成四组,先进行一次运算,之后再恢复 key 进行最终运算。
Hive 中数据倾斜的解决方案
  1. 参数调优
    1
    2
    set 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中),最后完成最终的聚合操作。

  1. join操作中,驱动表的选取
    1) 选取key分布均匀的表作为join的驱动表;做好列裁剪和过滤操作,以到达两个表join时,数据量相对变小的效果。
    2) 大小表join时,使用map join时,让小维度表现进入内存。
    3) 大表join大表时,把空值的key变成一个字符串加随机数,把倾斜的数据分布到不同的Reduce上,由于null值关联不上,处理后并不理解结果。
  2. 能先进行gourp by操作的先进行gourp by操作,把key先进行一次Reduce之后再进行count或者distinct count操作。

参考文章

MapReduce如何解决数据倾斜?
面试必问&数据倾斜