真正让你明白Hive调优系列4:hive中关于所有数据倾斜的处理

1.什么是数据倾斜?

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

2.Hive中会出现数据倾斜的地方?

  数据倾斜,这个是Hive优化的重头戏。出现的原因是因为出现了数据的重新分发和分布,启动了redcue。Hive中数据倾斜分类

  1.  join产生的数据倾斜
  2.  count(distinct)
  3. group by
  4. 一些窗口函数中用了partition by一会造成数据倾斜

3.分类介绍演示

3.1.join产生的数据倾斜

3.1.1大表和小表join产生的数据倾斜

     比如,一个上千万行的记录表和一个几千行表之间join关联时,容易发生数据倾斜。为什么大表和小表容易发生数据倾斜(无非有的reduce执行时间被延迟)具体小表join大表数据倾斜请使用请参考真正让你明白Hive调优系列3:笛卡尔乘积,小表join大表,Mapjoin等问题     

解决方式

1.多表关联时,将小表(关联键记录少的表)依次放到前面,这样可以触发reduce端更少的操作次数,减少运行时间。

 2.同时可以使用Map Join让小的维度表缓存到内存。在map端完成join过程,从而省略掉redcue端的工作。但是使用这个功能,需要开启map-side join的设置属性:set hive.auto.convert.join=true(默认是false)

同时还可以设置使用这个优化的小表的大小:set hive.mapjoin.smalltable.filesize=25000000(默认值25M)

3.1.2.大表和大表的join产生的数据倾斜

大表跟大表的join数据倾斜有几种解决方式,具体请参考:

1.比如:大表与大表关联,但是其中一张表的多是空值或者0比较多,容易shuffle给一个reduce,造成运行慢

解决方式1

1.这种情况可以对异常值赋一个随机值来分散key,均匀分配给多个reduce去执行,比如:

select  ...忽略......

from trackinfo a left outer join pm_info b

on ( case when (a.ext_field7 is not null and length(a.ext_field7) > 0    and a.ext_field7 rlike '^[0-9]+$')

      then cast(a.ext_field7 as bigint)

      else cast(ceiling(rand() * -65535) as bigint) end = b.id ) 

  #将A表垃圾数据(为null,为0,以及其他类型的数据)赋一个随机的负数,然后将这些数据shuffle到不同reduce处理。

解决方式2:

2.当key值都是有效值时,解决办法为设置以下几个参数

set hive.exec.reducers.bytes.per.reducer = 1000000000

也就是每个节点的reduce 默认是处理1G大小的数据,如果你的join 操作也产生了数据倾斜,那么你可以在hive 中设定

set hive.optimize.skewjoin = true;

set hive.skewjoin.key = skew_key_threshold (default = 100000)

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

    倾斜是经常会存在的,一般select 的层数超过2层,翻译成执行计划多于3个以上的mapreduce job 都很容易产生倾斜,建议每次运行比较复杂的sql 之前都可以设一下这个参数. 如果你不知道设置多少,可以就按官方默认的1个reduce 只处理1G 的算法,那么  skew_key_threshold  = 1G/平均行长. 或者默认直接设成250000000 (差不多算平均行长4个字节)

3.2 group by 造成的数据倾斜

      使用Hive对数据做一些类型统计的时候遇到过某种类型的数据量特别多,而其他类型数据的数据量特别少。当按照类型进行group by的时候,会将相同的group by字段的reduce任务需要的数据拉取到同一个节点进行聚合,而当其中每一组的数据量过大时,会出现其他组的计算已经完成而这里还没计算完成,其他节点的一直等待这个节点的任务执行完成,所以会看到一直map 100%  reduce 99%的情况。

解决方式很简单,设置参数:

hive.map.aggr=true  (默认true) 这个配置项代表是否在map端进行聚合,相当于Combiner

hive.groupby.skewindata=true(默认false)

有数据倾斜的时候进行负载均衡,当选项设定为 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作

3.3.count(distinct)以及其他参数不当的数据倾斜

3.3.1.比如设置的reduce个数太少

因为参数设置不当,reduce数太少,set mapred.reduce.tasks=800;

默认是先设置hive.exec.reducers.bytes.per.reducer这个参数,设置了后hive会自动计算reduce的个数,因此两个参数一般不同时使用

3.3.2.当HiveQL中包含count(distinct)时

   如果数据量非常大,执行如select a,count(distinct b) from t group by a;类型的SQL时,会出现数据倾斜的问题。

   解决方法:使用sum...group by代替。如select a,sum(1) from (select a, b from t group by a,b) group by a;

3.3.3 窗口函数中partition by造成的数据倾斜

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

涤生大数据

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值