5.Hive优化-数据倾斜

5.Hive优化-数据倾斜

5.1 什么是数据倾斜

数据倾斜主要表现在,map/reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条Key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完。

5.2 hive优化数据倾斜

5.2.1 map端聚合group by造成数据倾斜

Group By 中的计算均衡优化

select gender,count(1) from user1 group by gender;

 

如果没有map端的部分聚合优化,map直接把groupby_key 当作reduce_key发送给reduce做聚合,就会导致计算不均衡的现象。虽然map有100万个,但是reduce只有两个在做聚合,每个reduce处理100亿条记录。

hive.map.aggr=true

Map 端部分聚合,相当于Combiner    

 

开发:

创建表

create table user1(id int,gender string)

row format delimited fields terminated by ','

stored as textfile;

create table user2(id int,age int)

row format delimited fields terminated by ','

stored as textfile;

原始数据

[hadoop@h201 hhh]$ cat user1.txt

10001,male

10002,female

10003,male

10004,female

10005,male

[hadoop@h201 hhh]$ cat user2.txt

10001,20

10002,30

10003,40

10004,50

10005,60

导入数据

hive> load data local inpath '/home/hadoop/hhh/user1.txt' into table user1;

hive> insert into user1 select * from user1;

反复多次插入数据

hive> load data local inpath '/home/hadoop/hhh/user2.txt' into table user2;

set hive.map.aggr=true;

set hive.groupby.mapaggr.checkinterval = 100000;

set hive.map.aggr.hash.min.reduction=0.5;

说明:

Map开始的时候先尝试给前100000 条记录做hash聚合,如果聚合后的记录数/100000>0.5说明这个groupby_key没有什么重复的,再继续做局部聚合没有意义,100000 以后就自动把聚合开关关掉

5.2.2 count(distinct)造成数据倾斜

注意:

工作中无论是distinct还是count(distinct user_id)的操作,都不建议使用,因为distinct本身会有一个全局排序的过程,导致计算效率很低,通常会以group by的方式替

select count(distinct gender)  from user1;

替换为

select count(*) from user1 group by gender;

5.2.3聚合时存在大量null值

如果Null值较多,会导致分到Null值的Reduce处理的数据量过大,产生数据倾斜。

(1)select时

select count(*) from user1 group by gender;

替换为

select count(*) from user1 where gender is not null group by gender;

  1. join时

select a.gender,b.age from (select id,gender from user1 where id is not null) a

join (select id,age from user2 where id is not null) b

where a.id=b.id;

  1. 当user1表id为空需要保留时并替换成随机值

select a.id,a.gender,b.id,b.age from user1 a left join user2 b

on case when a.id is null then concat(99,111) else a.id end = b.id;

5.2.4不同数据类型关联产生数据倾斜

创建user3表(id字段为string)

create table user3(id string,address string)

row format delimited fields terminated by ','

stored as textfile;

原始数据

[hadoop@h201 hhh]$ cat user3.txt

10001,bj

aa123,sh

aa199,sh

10002,gz

10003,hb

导入数据

hive> load data local inpath '/home/hadoop/hhh/user3.txt' into table user3;

当按照两个表的id 进行join 操作的时候,默认的hash操作会按照int类型的id 进行分配,这样就会导致所有的string 类型的id就被分到同一个reducer当中,造成数据倾斜。

修改为:

select a.gender,b.address from user1 a join user3  b

on b.id = cast(a.id as string);

5.2.5 大小表关联查询产生数据倾斜

方法1:

Hive在进行join时,按照join的key进行分发,而在join左边的表的数据会首先读入内存,如果左边表的key相对分散,读入内存的数据会比较小,join任务执行会比较快。 而如果左边的表key比较集中,而这张表的数据量很大,那么数据倾斜就会比较严重,而如果这张表是小表,则还是应该把这张表放在join左边。原则即是小表在左,大表在右。

假设user1上有10亿条数据,user2上有5万条数据,遵循小表在左面的原则,应该user2 join user1。

hive> select user2.age,user1.gender from user2 join user1 where user2.id=user1.id;

方法2:

map join解决小表关联大表造成的数据倾斜问题,其是将其中做连接的小表(全量数据)分发到所有Map端进行Join,从而避免了reduce任务,当小表全量数据很小的时候可进行此操作。

hive> select /* +mapjoin(user2) */ user2.age,user1.gender from user2 join user1 where user2.id=user1.id;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值