MapReduce中数据倾斜的产生和解决办法详解

简介: MapReduce中数据倾斜的产生和解决办法详解

说明:关于数据倾斜的产生原因我将结合 map 和 reduce 阶段中的 shuffle 来讲解,若是对 shuffle 有所忘记需要温故的请到 MapReduce:详解Shuffle(copy,sort,merge)过程 进行相关了解。另本人能力有限,仅根据自己所了解的知识回答,若有误处或不足之处望不吝指出。


一、什么是数据倾斜以及数据倾斜是怎么产生的?


   简单来说数据倾斜就是数据的key 的分化严重不均,造成一部分数据很多,一部分数据很少的局面。


   举个 word count 的入门例子,它的map 阶段就是形成 (“aaa”,1)的形式,然后在reduce 阶段进行 value 相加,得出 “aaa” 出现的次数。若进行 word count 的文本有100G,其中 80G 全部是 “aaa” 剩下 20G 是其余单词,那就会形成 80G 的数据量交给一个 reduce 进行相加,其余 20G 根据 key 不同分散到不同 reduce 进行相加的情况。如此就造成了数据倾斜,临床反应就是 reduce 跑到 99%然后一直在原地等着 那80G 的reduce 跑完。


   简化了的 shuffle 图就是这样。


q1.png



   这样就能清楚看到,数据经过 map后,由于不同key 的数据量分布不均,在shuffle 阶段中通过 partition 将相同的 key 的数据打上发往同一个 reducer 的标记,然后开始 spill (溢写)写入磁盘,最后merge成最终map阶段输出文件。


   如此一来 80G 的 aaa 将发往同一个 reducer ,由此就可以知道 reduce 最后 1% 的工作在等什么了。


二、为什么说数据倾斜与业务逻辑和数据量有关?


   从另外角度看数据倾斜,其本质还是在单台节点在执行那一部分数据reduce任务的时候,由于数据量大,跑不动,造成任务卡住。若是这台节点机器内存够大,CPU、网络等资源充足,跑 80G 左右的数据量和跑10M 数据量所耗时间不是很大差距,那么也就不存在问题,倾斜就倾斜吧,反正机器跑的动。所以机器配置和数据量存在一个合理的比例,一旦数据量远超机器的极限,那么不管每个key的数据如何分布,总会有一个key的数据量超出机器的能力,造成 reduce 缓慢甚至卡顿。


   业务逻辑造成的数据倾斜会多很多,日常使用过程中,容易造成数据倾斜的原因可以归纳为几点,有前辈早就整理好,我就搬砖了:


分组

注:group by 优于distinct

group

情形:group by 维度过小,某值的数量过多

后果:处理某值的reduce非常耗时


去重

distinct

count(distinct xx)

情形:某特殊值过多

后果:处理此特殊值的reduce耗时


连接

join

情形1:其中一个表较小,但是key集中

后果1:分发到某一个或几个Reduce上的数据远高于平均值

情形2:大表与大表,但是分桶的判断字段0值或空值过多

后果2:这些空值都由一个reduce处理,非常慢


三、如何处理数据倾斜问题呢?


   1、调优参数


set hive.map.aggr=true;
    set hive.groupby.skewindata=true;


hive.map.aggr=true:在map中会做部分聚集操作,效率更高但需要更多的内存。


hive.groupby.skewindata=true:数据倾斜时负载均衡,当选项设定为true,生成的查询计划会有两个MRJob。第一个MRJob 中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的GroupBy Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MRJob再根据预处理的数据结果按照GroupBy Key分布到Reduce中(这个过程可以保证相同的GroupBy Key被分布到同一个Reduce中),最后完成最终的聚合操作。


   由上面可以看出起到至关重要的作用的其实是第二个参数的设置,它使计算变成了两个mapreduce,先在第一个中在 shuffle 过程 partition 时随机给 key 打标记,使每个key 随机均匀分布到各个 reduce 上计算,但是这样只能完成部分计算,因为相同key没有分配到相同reduce上,所以需要第二次的mapreduce,这次就回归正常 shuffle,但是数据分布不均匀的问题在第一次mapreduce已经有了很大的改善,因此基本解决数据倾斜。


   2、二次运算,在 key 上面做文章,在 map 阶段将造成倾斜的key 先分成多组,例如 aaa 这个 key,map 时随机在 aaa 后面加上 1,2,3,4 这四个数字之一,把 key 先分成四组,先进行一次运算,之后再恢复 key 进行最终运算。


   3、能先进行 group 操作的时候先进行 group 操作,把 key 先进行一次 reduce,之后再进行 count 或者 distinct count 操作。


   4、join 操作中,使用 map join 在 map 端就先进行 join ,免得到reduce 时卡住。


相关文章
|
7月前
|
缓存 分布式计算 负载均衡
如何在MapReduce中处理数据倾斜问题?
如何在MapReduce中处理数据倾斜问题?
192 0
|
7月前
|
分布式计算
MapReduce【数据倾斜的优化】
MapReduce【数据倾斜的优化】
|
分布式计算 Hadoop
MapReduce之数据倾斜问题
MapReduce是分为Map阶段和Reduce阶段,其实提高执行效率就是提高这两个阶段的执行效率
132 0
|
分布式计算 负载均衡 Hadoop
【Hadoop】(五)MapReduce 如何解决数据倾斜问题
【Hadoop】(五)MapReduce 如何解决数据倾斜问题
831 0
【Hadoop】(五)MapReduce 如何解决数据倾斜问题
|
分布式计算 Ubuntu Hadoop
Ubuntu系统下eclipse配置mapreduce插件常见错误和解决办法汇总
在上篇文章中eclipse已经能访问HDFS目录( blog.csdn.net/gamer_gyt/article/details/47209623),但并不能进行Mapreduce编程,在这里小编将常见错误和处理办法进行总结,希望对大家有所帮助 错误1:ERROR [main] util.
1755 0
|
7月前
|
分布式计算 Hadoop
Hadoop系列 mapreduce 原理分析
Hadoop系列 mapreduce 原理分析
86 1
|
2月前
|
分布式计算 资源调度 Hadoop
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
119 3
|
6月前
|
分布式计算 Hadoop Java
Hadoop MapReduce编程
该教程指导编写Hadoop MapReduce程序处理天气数据。任务包括计算每个城市ID的最高、最低气温、气温出现次数和平均气温。在读取数据时需忽略表头,且数据应为整数。教程中提供了环境变量设置、Java编译、jar包创建及MapReduce执行的步骤说明,但假设读者已具备基础操作技能。此外,还提到一个扩展练习,通过分区功能将具有相同尾数的数字分组到不同文件。
68 1
|
6月前
|
数据采集 SQL 分布式计算
|
7月前
|
分布式计算 Hadoop Java
Hadoop MapReduce 调优参数
对于 Hadoop v3.1.3,针对三台4核4G服务器的MapReduce调优参数包括:`mapreduce.reduce.shuffle.parallelcopies`设为10以加速Shuffle,`mapreduce.reduce.shuffle.input.buffer.percent`和`mapreduce.reduce.shuffle.merge.percent`分别设为0.8以减少磁盘IO。
78 1