HIVESQL数据倾斜干货

HIVESQL数据倾斜干货_第1张图片数据倾斜的几种常见场景:

1.distinct
2.group by
3.reducejoin
4.动态分区

1可以转换到2,2可以加参数就可以解决,原理在于预处理
参数:set hive.groupby.skewindata=true; --如果是group by过程出现倾斜 应该设置为true,这种方法会启动两个job,第一个job会在key前面添加一个随机数,将数据散列到reduce中,第二个job就是将key前面的随机数去掉进行聚合。

对于常见的情况3,是发生在关联处(比如on a.id=b.id),处理措施如下:

(首先考虑下数据取数范围、过滤条件,尽早过滤数据)

先查看a.id的数据量分布情况,

select id,count(1) as num from a group by id order by num desc

A:若是发现有大量null情况,就赋随机值处理

on (nvl(a.id,concat('HIVE_',rand())=b.id)
这样随机值就会打散reduce分布的数量,效果明显,原本要1小时的可以在1min内跑完	

B:若是a.id的值有业务含义,此时就不能草率赋随机值,此时应该查看维表b的数据量情况,若是一张小表,hive已经优化走mapjoin不必关心,但生产环境数据量以及数据的分布情况是不可预估的,就需要做特殊处理了。

B-1:维表b的业务上数据过滤

所谓业务上数据过滤,举个例子
腾讯会员的维表肯定非常大,几个亿的数据量是有的,如此大的维表关联必定走reducejoin。但考虑到你统计的数据范围,一般不会涉及到所有会员,仅涉及一部分会员,单次活动可能就涉及几百几千会员id。所以先将这些会员先提取出来再与事实表a关联就可能会走mapjoin了。具体做法:

	select  
		 user_id
		,user_nm 
	from 
	(
		select user_id from a group by user_id
	) as eff_user
	inner join 
		hy 
	on (eff_user.user_id=hy.id)
	
以上就可能将会员维表由10个亿锐减到几千条数据,进而直接走mapjoin
至于代码中的groupby可以参考开始的参数调优。

B-2:冷热分离

	就是根据
	select id,count(1) as num from a group by id order by num desc
	查询到的数据分布对事实表分开处理,热点id的数据参考B-1的方法走mapjoin,
	非热点数据就走普通的reducejoin,必要时多开几个reduce,提高处理效率

熟悉业务的,比如统计单次活动,活动在北京举行的,就可以直接将北京数据单独拉出来处理,最后unionall 合并起来
通用一点的做法就是将count(1)大于某一值的数据全部拉出来单独处理。比如1个亿,(之前碰到一个天任务,有7个亿的NULL情况,一般跑60min),同样非热点数据多开启reduce高效处理。
以上是对常见的关联倾斜的优化处理,还是比较干货满满的,本人目前接触的数据量也不算太大,可能还有些情况未遇到,还请各位补充指教。

对于第4种情况的null,倾斜的资料很少有提到,我遇到过一次,特在此写出,供大家参考
场景:小表与大表的全关联,关联键确认是唯一的,最后动态分区。
原因分析:
关联键唯一,数据量差异巨大,必然导致大表很多数据关联不上,所以就有很多空值NULL出现,当动态分区字段的取值逻辑用到了大表关联不上的字段后就会随之出现大量的NULL情况,落数据阶段优于是动态分区,null的全部由一个reduce处理,就出现数据倾斜的情况。
此时应该首先冷静分析一下业务处理逻辑是否正常(当时我的逻辑就是不对)
真要遇到此种情况,

可以冷热分离,将NULL的单独拎出来用静态分区的方式插入数据,	

也可以用随机值的方式

distribute by rand()。

你可能感兴趣的:(HIVE数据倾斜)