hive数据倾斜解决方法

Hive的过程中经常会碰到数据倾斜问题,数据倾斜基本都发生在group、join等需要数据shuffle的操作中,这些过程需要按照key值进行数据汇集处理,如果key值过于集中,在汇集过程中大部分数据汇集到一台机器上,这就会导致数据倾斜。

具体表现为:作业经常reduce完成在99%后一直卡住,最后的1%花了几个小时都没有跑完。

常见产生数据倾斜的原因:
#空值产生的数据倾斜
#不同数据类型关联产生的数据倾斜
#关联的key非空,但是某个key值大量重复 #distinct、count(distinct)

1、 空值产生的数据倾斜场景:
如日志中,常会有信息丢失的问题,比如全网日志中的user_id,如果取其中的user_id和bmw_users关联,会碰到数据倾斜的问题。
解决方法1:
user_id为空的不参与关联

select * 
from log a
join bmw_users b
on a.user_id is not null
and a.user_id = b.user_id
union all
select * 
from log a
where a.user_id is null;

解决方法2 :
赋与空值分新的key值(推荐)

select * 
from logs a 
left join bmw_users b 
on case when a.user_id is null then concat(‘dp_hive’,rand() ) 

#把空值的key变成一个字符串加上随机数else a.user_id end = b.user_id;

2、 不同数据类型关联产生数据倾斜场景:
用户表中user_id字段为int,logs表中user_id字段既有string类型也有int类型。当按照user_id进行两个表的join操作时,默认的Hash操作会按照int型的id来进行分配,这样会导致所有string类型的id记录都分配到同一个reduce中。
解决方法:
把数字类型转换成字符串类型

select * 
from users a
left join logs b
on a.user_id = cast(b.user_id as string)

3、关联的key非空,但是某个key值大量重复
解决方法:
加入随机数

select a.key as key, b.pv as pv 
from(
select key 
from table1 
where dt='2018-06-18') a
left join(
select key, sum(pv) as pv 	 
from (
select key,	round(rand()*1000) as rnd, #加入随机数,增加并发度		
count(1) as pv		
from table2 
where dt='2018-06-18' group by key,rnd) tmp    
group by key) b 
on a.key = b.key

4、distinct、count(distinct)
解决方法:
用group by 去重
#distinct替换:
原始sql:

select distinct key from A;		

替换后的sql:

select key from A group by key;

#单维度count(distinct)替换
原始sql:

select ship_id, count(distinct order_id) as ship_order_num			
from table A			
where dt = '2018-06-18' 
group by ship_id;

替换后的sql:

select ship_id, count(1) as ship_order_num			
from 			
(select ship_id, order_id 
from table A 
where dt = '2018-06-18' 
group by ship_id, order_id) t			
group by ship_id;	

#多维度count(distinct)替换 —每个维度单独处理后关联

猜你喜欢

转载自blog.csdn.net/weixin_38799368/article/details/83106976