数据倾斜是进行大数据计算时常见的问题。主要分为map端倾斜和reduce端倾斜,map端倾斜主要是由于输入文件大小不均匀致使,reduce端主要是partition不均匀致使。html
在hive中遇到数据倾斜的解决办法:缓存
1、倾斜缘由:map端缓慢,输入数据文件多,大小不均匀负载均衡
当出现小文件过多,须要合并小文件。能够经过set hive.merge.mapfiles=true来解决。大数据
set hive.map.aggr=true; //map端部分聚合,至关于Combiner,能够减少压力(默认开启)优化
set hive.groupby.skewindata=true(默认关闭);//有数据倾斜的时候进行负载均衡,当选项设定为 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每一个 Reduce 作部分聚合操做,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不一样的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程能够保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操做。日志
单个文件大小稍稍大于配置的block块的大写,此时须要适当增长map的个数。解决方法:set mapred.map.tasks个数code
文件大小适中,但map端计算量很是大,如select id,count(*),sum(case when...),sum(case when...)...须要增长map个数。解决方法:set mapred.map.tasks个数,set mapred.reduce.tasks个数orm
2、当遇到一个大表和一个小表进行join操做时htm
解决方法:小表在join左侧,大表在右侧,或使用mapjoin 将小表加载到内存中。而后再对比较大的表进行map操做。blog
join就发生在map操做的时候,这里的join并不会涉及reduce操做。map端join的优点就是在于没有shuffle,
如:select /*+ MAPJOIN(a) */
a.c1, b.c1 ,b.c2 from a join b
where a.c1 = b.c1;
3、遇到须要进行join的可是关联字段有数据为null,如表一的id须要和表二的id进行关联,null值的reduce就会落到一个节点上
解决方法1:子查询中过滤掉null值,id为空的不参与关联
解决方法2:用case when给空值分配随机的key值(字符串+rand())
4、不一样数据类型关联产生数据倾斜
场景:一张表s8的日志,每一个商品一条记录,要和商品表关联。但关联却碰到倾斜的问题。s8的日志中有字符串商品id,也有数字的商品id,类型是string的,但商品中的数字id是bigint的。猜想问题的缘由是把s8的商品id转成数字id作hash来分配reduce,因此字符串id的s8日志,都到一个reduce上了,解决的方法验证了这个猜想。
解决方法:把数字类型转换成字符串类型
Select * from s8_log a Left outer join r_auction_auctions b On a.auction_id = cast(b.auction_id as string);
5、当HiveQL中包含count(distinct)时
若是数据量很是大,执行如select a,count(distinct b) from t group by a;类型的SQL时,会出现数据倾斜的问题。
解决方法:使用sum...group by代替。如select a,sum(1) from (select a, b from t group by a,b) group by a;
6、join和Group的优化
2.1 对于普通的join操做,会在map端根据key的hash值,shuffle到某一个reduce上去,在reduce端作join链接操做,内存中缓存join左边的表,遍历右边的表,一次作join操做。因此在作join操做时候,将数据量多的表放在join的右边。
当数据量比较大,而且key分布不均匀,大量的key都shuffle到一个reduce上了,就出现了数据的倾斜。
在map端产生join
mapJoin的主要意思就是,当连接的两个表是一个比较小的表和一个特别大的表的时候,咱们把比较小的table直接放到内存中去,而后再对比较大的表格进行map操做。join就发生在map操做的时候,每当扫描一个大的table中的数据,就要去去查看小表的数据,哪条与之相符,继而进行链接。这里的join并不会涉及reduce操做。map端join的优点就是在于没有shuffle,
2.2 对于Group操做,首先在map端聚合,最后在reduce端坐聚合,hive默认是这样的,如下是相关的参数
· hive.map.aggr = true是否在 Map 端进行聚合,默认为 True
· hive.groupby.mapaggr.checkinterval = 100000在 Map 端进行聚合操做的条目数目
转载自:https://www.cnblogs.com/kongcong/p/7777092.html