【数据倾斜原因及处理】

数据倾斜原因及处理

一、原因

1)、key分布不均匀
2)、业务数据本身的特性
3)、建表时考虑不周
4)、某些SQL语句本身就有数据倾斜

操作情形
group bygroup by 维度过小,某值的数量过多
Count Distinct某特殊值过多
Join大表join小表,其中小表key集中,分发到某一个或几个reduce上的数据远高于平均值

二、数据倾斜的解决方案

2.1参数调节(group by造成数据倾斜)

set hive.map.aggr=true 设置在Map端进行聚合
set hive.groupby.skewindata = true 实现方法是在group by时启动两个MR job。第一个job会将map端数据随机输入reducer,每个reducer做部分聚合,相同的key就会分布在不同的reducer中。第二个job再将前面预处理过的数据按key聚合并输出结果,这样就起到了均衡的效果

select word,count(word) from wordtest group by wordtest
案例:统计单词数量,假设单词d数据倾斜
with
dt as (select word, num, row_number () over () rn from wordtest where word='d'),
dd as (select rn%3 t, sum (num) total from dt group by rn%3),
df as (select 'd' word, sum (total) total from dd),
dw as (select word , sum(num) total from wordtest where word<>'d' group by word)select * from df union all select * from dw;

2.2 Sql语句优化

如果数据量非常大,执行如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;

2.3空值产生的数据倾斜:

解决方法1:空值不参与关联

select * from log a
  join users b
  on a.user_id is not null
  and a.user_id = b.user_id
union all
select * from log a
  where a.user_id is null;

解决方法2 :赋予空值新的key值

select * from log a
left outer join users b
on case when a.user_id is null then concat(‘hive’,rand() ) else a.user_id end = b.user_id;

结论:方法2比方法1效率更好,解决方法1中 log读取两次,jobs是2。解决方法2 job数是1 。这个优化适合无效 id 产生的倾斜问题。把空值的 key 变成一个字符串加上随机数,就能把倾斜的数据分到不同的reduce上 ,解决数据倾斜问题。

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

默认的Hash操作会按int型的id来进行分配,这样会导致所有string类型id的记录都分配到一个Reducer中

select * from users a left outer join logs b
on a.usr_id = cast(b.user_id as string)

2.5大表join小表

map join 概念:将其中做连接的小表(全量数据)分发到所有 MapTask 端进行 Join,从 而避免了 reduceTask,前提要求是内存足以装下该全量数据

set hive.auto.convert.join= true
set hive.mapjoin.smalltable.filesize`,当小表小于该值就会启用map join,默认值2500000025MB)

2.6大表join大表

解决办法1:参数设置

set hive.optmize.skewjoin=true
set hive.skewjoin.key=100000; #默认为100000

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

解决办法2:从其中一个大表中提取join字段形成小表,再和大表进行join

select * from log a
 left outer join (
    select  d.*
      from ( select distinct user_id from log ) c
      join users d
      on c.user_id = d.user_id
    ) x
  on a.user_id = b.user_id;

转载链接: https://blog.csdn.net/mqd_chan/article/details/114271037.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Hive数据倾斜主要是由于数据分布不均匀引起的。具体原因如下: 1. 数据分布不均:Hive是基于Hadoop分布式计算框架的,将大数据集分成若干个小数据块进行并行处理。如果数据分布不均匀,例如某些关键字段的取值范围过小导致某些数据块比其他数据块要大很多,则处理这些数据块的任务会变得非常繁重,导致数据倾斜。 2. 键值的不平衡:在Hive中,经常会根据某些字段进行分组、聚合等操作,如果某个字段的取值分布非常不均匀,则在处理这个字段相关的任务时会产生数据倾斜。例如,某个字段的取值范围中有一个非常常见的值,而其他值的频率相对较低,这会导致该常见值所在的任务负担非常重。 3. 数据倾斜的表现:当发生数据倾斜时,我们可以通过以下表现来判断: - 任务执行时间过长:倾斜的数据块会导致某些任务处理时间过长,整个任务的执行时间明显延长。 - 部分节点资源消耗过多:有些节点可能需要处理大量的倾斜数据,导致这些节点的资源消耗非常大。 - MapReduce作业阶段失败:在倾斜数据处理的过程中,可能会导致作业某些阶段的失败,需要进行重新执行。 - 资源利用率不均衡:倾斜数据的存在会导致一些节点的资源利用率非常高,而其他节点资源利用率较低。 为了解决数据倾斜问题,可以采取以下措施: 1. 数据预处理:对数据进行分桶、分区等操作,使得数据均匀分布,减轻数据倾斜问题。 2. 优化数据倾斜字段的处理逻辑:对于倾斜字段的处理逻辑进行优化,减轻数据倾斜的影响。 3. 动态调整任务大小:根据任务的数据倾斜情况,动态调整任务大小,使得负载均衡。 4. 使用随机数解决倾斜问题:在分区、分组等操作中,引入随机数,将数据均匀分布到不同的节点上,减轻数据倾斜。 5. 使用特定的函数处理倾斜数据:例如使用UDF函数等来处理倾斜数据,优化性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值