hive数据倾斜的优化

一.join操作数据倾斜

1.mapjoin

map join 默认开启

set hive.auto.convert.join = true0.11版本后默认是trueset hive.mapjoin.smalltable.filesize=25000000(设置小表的大小,默认就是25M)

不管大小表放左边还是右边,自动将小表放入内存,然后在map端顺序扫描大表跟内存中的数据进行join,没有reduce阶段,没有shuffle

2.类型不一致

关联字段不一致引发的数据倾斜操作有一个a表关联字段是string类型,b表关联字段是bigint类型,将bigint转换为string类型就可以了

select
a.guid,
a.oid,
b.name
from a
join b
on a.guid=cast(b.guid as string)
3.特殊值过多

如null,空,0导致的数据倾斜
可以将特殊值加盐,可以打散到多个reduce中

select
b.guid,
a.oid,
b.name
from a
join b
on (case when a.guid is null or a.guid=0 or a.guid='null' then CONCAT('hive',RAND()) else a.guid end) = b.guid
4.大表join大表skewjoin

1.综合以上几点,先进行 行列过滤,然后有特殊值将特殊值加盐,类型不一致的类型转换一致
除此之外,还可以skewjoin开启join倾斜优化参数

set hive.optimize.skewjoin=true;
set hive.skewjoin.key=100000;   --(处理的总记录数/reduce个数)的2-4倍都可以接受

hive 在运行的时候没有办法判断哪个key 会产生多大的倾斜,所以使用这个参数控制倾斜的阈值,如果超过这个值,新的值会发送给那些还没有达到的reduce, 一般可以设置成你处理的(总记录数/reduce个数)的2-4倍都可以接受

原理:

对于skewjoin.key,在执行job时,将它们存入临时的HDFS目录,其它数据正常执行;
对倾斜数据开启map join操作,对非倾斜值采取普通join操作;
将倾斜数据集和非倾斜数据及进行合并操作。

2.先抽样,看key的分布情况,倾斜key都是需要的数据,不能过滤,左表中有大key,右表中每个key只有一条记录,可以将左表倾斜数据和不倾斜数据分开进行mapjoin,就不会发生数据倾斜了,最后将两部分结果合并到一起

如果是右表中相同key有多条记录,然后可以将左表中倾斜数据添加随机数前缀,然后将右表倾斜数据进行膨胀并添加随机数前缀,两部分添加随机数前缀的数据进行join,这样所有倾斜key就被打散到了多个reduce中进行join操作,再去除随机数前缀.让后将左右表不倾斜数据进行jion和去除随机数前缀的数据union到一起.

5.简单的增加 reduce 并行个数
set mapred.reduce.tasks=100

二.group by操作数据倾斜

1.map端聚合

在map端部分聚合,然后在reduce端全局聚合

set hive.map.aggr = true;
2.开启group by负载均衡参数,会分两阶段聚合

原理如3

set hive.groupby.skewindata=true;
3.在sql中给group by的key加盐

在sql中给group by的key加盐,将key打散到多个reduce中
先聚合一次,然后将第一阶段的结果中key去除随机数,然后再总的聚合.明显第一阶段使相同的key都打散到了多个reduce中,并且拉去到
第二阶段reduce中的数据明显减少,这就是两阶段聚合.

select
user_id,
sum(cts) as s_cts
from
(
select
user_id,
round(rand()*1000) as rk,  --根据具体情况设置随机数的范围
count(1) as cts
from group_t
group by user_id,round(rand()*1000) --根据具体情况设置随机数的范围
) t1
group by user_id
4.避免count(distinct)操作
count(distinct)操作是用一个reduce来完成的,如果数据量很大,会导致整个job很难完成
使用sum()  group by 代替
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值