文章目录
一、什么是数据倾斜
由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点
二、Hadoop框架的特性
- 不怕数据大,怕数据倾斜
- Jobs 数比较多的作业运行效率相对比较低,如子查询比较多
- sum,count,max,min 等聚集函数,通常不会有数据倾斜问题
三、主要表现
在8088端口,查看任务进度维持在99%或者100%附近,查看任务监控界面,发现只有少量的reduce任务未完成,因为其处理的数据量和其他reduce的差异过大,最长时间远大于平均时间,这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完。
四、容易产生数据倾斜的情况
- group by 不和聚集函数搭配使用的时候
- count(distinct),在数据量大的情况下,容易数据倾斜,因为count(distinct)是按group by 字段分组,按distinct 字段排序
- 小表关联超大表 join
五、产生数据倾斜的原因
- key 分布不均匀
- 业务数据本身的特性
- 建表考虑不周全
- 某些 HQL 语句本身就存在数据倾斜
六、业务场景
1、空值产生的数据倾斜
解决方法
1:user_id 为空的不参与关联
select * from log a join user b on a.user_id is not null and a.user_id = b.user_id
union all
select * from log c where c.user_id is null;
2:赋予空值新的 key 值
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
2、不同数据类型关联产生数据倾斜
解决方法
通过cast转换字段类型
select * from user a left outer join log b on b.user_id = cast(a.user_id as string)
3、大小表关联查询产生数据倾斜
使用map join解决小表关联大表造成的数据倾斜问题
map join 概念:将其中做连接的小表(全量数据)分发到所有 MapTask 端进行 Join,从 而避免了 reduceTask,前提要求是内存足以装下该全量数据
在 hive0.11 版本以后会自动开启 map join 优化,由两个参数控制:
set hive.auto.convert.join=true; //设置 MapJoin 优化自动开启
set hive.mapjoin.smalltable.filesize=25000000 //设置小表不超过多大时开启 mapjoin 优化
原文地址:Hive的数据倾斜