MapReduce数据倾斜产生的原因及其解决方案

1、数据倾斜现象

数据倾斜就是数据的key的分化严重不均,造成一部分数据很多,一部分数据很少的局面。
数据频率倾斜 —— 某一个区域的数据量要远远大于其他区域。
数据大小倾斜 —— 部分记录的大小远远大于平均值。

2、数据倾斜产生的原因

(1)Hadoop框架的特性

Job数多的作业运行效率会相对比较低;
countdistinct、group by、join等操作,触发了shuffle动作,导致全部相同key的值聚集在一个或几个节点上,很容易发生单点问题。

(2)具体原因

key 分布不均匀,某一个key的数据条数比其他key多太多;
业务数据自带的特性;
建表时考虑不全面;
可能某些 HQL 语句自身就存在数据倾斜问题。

3、数据倾斜解决方案

从业务和数据方面解决数据倾斜
有损的方法: 找到异常数据。
无损的方法:
对分布不均匀的数据,进行单独计算,首先对key做一层hash,把数据打散,让它的并行度变大,之后进行汇集数据预处理

Hadoop平台的解决方法

1)针对join产生的数据倾斜

场景一:大表和小表join产生的数据倾斜

① 在多表关联情况下,将小表(关联键记录少的表)依次放到前面,这样能够触发reduce端减少操作次数,从而减少运行时间。
② 同时使用Map Join让小表缓存到内存。在map端完成join过程,这样就能省掉redcue端的工作。

需要注意:这一功能使用时,需要开启map-side join的设置属性:

set hive.auto.convert.join=true #(默认是false)
③ 还可以对使用这个优化的小表的大小进行设置:
set hive.mapjoin.smalltable.filesize=25000000 #(默认值25M) 

场景二:大表和大表的join产生的数据倾斜

① 将异常值赋一个随机值,以此来分散key,均匀分配给多个reduce去执行
set hive.exec.reducers.bytes.per.reducer = 1000000000
② 如果key值都是有效值的情况下,需要设置以下几个参数来解决也就是每个节点的reduce,其 默认是处理数据地大小为1G,如果join 操作也产生了数据倾斜,那么就在hive 中设定
set hive.optimize.skewjoin = true;
set hive.skewjoin.key = skew_key_threshold  #(default = 100000)

2)group by 造成的数据倾斜

解决方式相对简单:

#(默认true) 这个配置项代表是否在map端进行聚合,相当于Combiner
hive.map.aggr=true 
hive.groupby.skewindata

3)count(distinct)或者其他参数不当造成的数据倾斜

① reduce个数太少
set mapred.reduce.tasks=800
② HiveQL中包含count(distinct)时

使用sum…group byl来替代。例如select a,sum(1) from (select a, b from t group by a,b) group by a;

你可能感兴趣的:(大数据,mapreduce,hadoop,大数据)