Hive数据倾斜

目录

数据倾斜

what

怎么判断/主要表现

why

小表join大表

倾斜场景

优化

map join不能解决的

大表join大表

不同数据类型关联

异常值(null/0)

group by

distinct转group by

优化之前

其他


数据倾斜

what

“倾斜”来自于统计学里的的偏态分布
数据分布不均匀,大量数据集中到一点,造成数据热点

怎么判断/主要表现

查看日志/任务监控页面,reduce节点大部分执行完毕,少数几个运行很慢或卡在某个进度(例如reduce = 80%/99%),导致整个任务的处理时间很长

因为reduce处理的记录数比平均记录数大几倍,最长时间远大于平均时长
某一个key的条数比其他key多很多(百倍、千倍)

why

key分布不均匀
业务数据本身的特性
建表考虑不周全
某些 HQL 语句本身就存在数据倾斜

map端:一般不会。对应一个逻辑切片
reduce端:很容易产生数据倾斜

本质:MR的数据倾斜
不患多而患不均

小表join大表

倾斜场景

如果小表的数据量比较少但key却比较集中,这就会导致分发到某一个或几个reduce上的数据比其他reduce多很多,造成数据倾斜

优化

使用map join将小表装入内存,在map端完成join操作,这样就避免了reduce操作

map join不能解决的

动态一分为二:不倾斜的键值正常join,倾斜的键值把它们找出来,做map join,最后union all其结果

缺点:这种解决方案比较麻烦,代码会变得复杂而且需要一个临时表存放倾斜的键值

大表join大表

不同数据类型关联

倾斜场景

int join int、string,默认的hash操作会按照int类型的id进行分配,这样就会导致所有的string类型的id被分到同一个reducer当中

优化

select * 
from user a left outer join log b 
on b.user_id = cast(a.user_id as string);

异常值(null/0)

倾斜场景:一张表异常值比较多(阈值),容易shuffle给一个reduce,造成运行慢
优化:对异常值赋值来分散key
Example
比如日志中缺失信息的user_id和用户表user_id关联
null赋值成string +随机数
1)分配给多个reduce去执行
2)null值关联不上,处理后并不影响最终结果

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

group by

倾斜场景:group by字段的某些值特别多,会将相同值拉到同一个reduce任务进行聚合

优化

开启map端聚合:hive.map.aggr=true(Hive 0.3默认)
在map端聚合的条目:set hive.groupby.mapaggr.checkinterval=100000(默认)
group by有数据倾斜时进行负载均衡:hive.groupby.skewindata=true(默认false)

distinct转group by

why

count(distinct)是用一个reduce任务完成,如果是大数量就会导致整个job很难完成
distinct本身会有一个全局排序的过程,导致计算效率很低

优化:group by替代distinct

-- 问题
select 
  count(distinct city) as cnt 
from user_list_detail 
where city is not null;

-- 解决
select count(*) cnt
from
  (select city
  from user_list_detail
  where city is not null
  group by city)tmp

优化之前

检查数据本身:使用的数据是否合理?是否复用数据?
使用习惯:使用HiveQL规范,例如,慎用distinct、count(distinct);扫描需要的分区是否合理?;是否过滤了无关的数据行;合并小文件

其他

开启倾斜连接优化:hive.optimize.skewjoin=true

在运行时,将检测到有较大偏差的键,临时存储在HDFS目录中,后续的MR作业(对于倾斜键)将会快得多,因为它将是一个map-join

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值