发生数据倾斜时,通常的现象是:
数据倾斜一般是由于代码中的join或group by或distinct的key分布不均导致的,大量经验表明数据倾斜的原因是人为的建表疏忽或业务可以规避的。如果确认业务需要这样倾斜的逻辑.
select /*+MAPJOIN(b)*/ * from a join b on a.id =b.id
将会把join转换为mapjoin,且将b表作为小表处理。
一、随机函数解决倾斜
原始sql:
insertoverwrite table t_aa_click_log partition (pt=’${yyyymmddhh}’)
selecta.*
from(select * from t_aa_click_log1
wherept=’${yyyymmddhh}’
)a
leftouter join
(select* from t_aa_pv_info_log
wherept=’${yyyymmddhh}’) b
ona.pvid=b.pvid;
发现大量时间花费在reduce99%~100%这最后一步上,约占总时长20分钟的一半,
用以下sql检查下数据分布:
select*
from(
selectpvid,count(1) cnt
fromt_aa_click_log1
wherept=’${yyyymmddhh}’
groupby pvid) t
orderby cnt desc
limit50;
发现pvid=’NA’的占比最高,有100多万,而其他最多的也只有几十条,证实数据倾斜。
利用随机函数,将pvid=’NA’的数据随机分布到不同的reduce中:
insertoverwrite table t_aa_click_log partition (pt=’${yyyymmddhh}’)
selecta.*
from(select * from t_aa_click_log1
wherept=’${yyyymmddhh}’
)a
leftouter join
(select* from t_aa_pv_info_log
wherept=’${yyyymmddhh}’) b
–如果pvid长度<=2,包含pvid=NA或-1 等多种异常值,即用随机函数叠加处理,因为异常值本来就关联不到,所以加上随机函数对结果没有影响
oncase when length(a.pvid)<=2 then concat(a.pvid,rand()) else a.pvid end =b.pvid;
问题解决。