概述
数据倾斜
一:什么是数据倾斜?
由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点 ,简单来说就是大量相同的key被partition到同一个分区里面导致某些或者某个reducetask压力过大,而一些reducetask闲住。这样也违背了并行计算的初衷。
二:数据倾斜的主要表现?
任务进度长时间维持在 99%或者 100%的附近,查看任务监控页面,发现只有少量 reduce 子任务未完成,因为其处理的数据量和其他的 reduce 差异过大。 单一 reduce 处理的记录数和平均记录数相差太大,通常达到好几倍之多,最长时间远大 于平均时长。
三:不容易产生数据倾斜的情况?
1)聚合函数 和 group by 一起使用的时候 ,在map端默认执行执行 combiner ,combiner是在map阶段,reduce之前的一个中间阶段,在这个阶段可以选择性的把大量的相同key数据先进行一个合并,可以看做是local reduce,然后再交给reduce来处理,这样做的好处很多,即减轻了map端向reduce端发送的数据量(减轻了网络带宽),也减轻了map端和reduce端中间的shuffle阶段的数据拉取数量(本地化磁盘IO速率),
2)只有map操作的时候,map中的key是唯一的,就不会存在很多相同的key被partiton到同一个分区;
3)某些查询hql语句 不会转换为mr
select * from stu_managed01
select * from stu_managed01 where age>19
select * from stu_managed01 where age>19 limit 3
select sid,name from stu_managed01 limit 10;
hive fetch 抓取
流
读取hdfs的数据的时候没有mr的参与:
通过命令行设置set hive.fetch.task.conversion=
1.none
这个参数禁用
所有的操作都没有fetch
都要转换为mr
2.minimal
SELECT *, FILTER on partition columns (WHERE and HAVING clauses), LIMIT only
1)select *
2) where 是分区字段
3)limit
3.more
SELECT, FILTER, LIMIT only (including TABLESAMPLE, virtual columns)
1)select 表任何原生字段
2)where
3)limit
group by
order by
distinct
聚合
mr
四:哪些场景容易产生数据倾斜?
- group by不和聚合函数一起使用的时候;
- count(distinct),在数据量大的情况下,容易数据倾斜,因为 count(distinct)是按 group by 字段分组,按 distinct 字段排序;
- 小表关联超大表 join
五:产生数据倾斜的原因?
- key 分布不均匀
- 业务数据本身的特性
- 建表考虑不周全
- 某些 HQL 语句本身就存在数据倾斜
六:数据倾斜的具体场景分析?
1)表连接的关联建存在大量空值
原因:
一旦关联键存在大量空值,在reduce的时候,大量null会被分配到一个redecetask中,可以去除null值,但是这就需要判断和解决null的问题,这需要计算,无疑增大了某一reducetask的压力,从而造成数据倾斜
解决方案:
1)null值不参与连接
select
*
from user a
join (
select * from log where userid is not null
) b on a.userid=b.userid
union
select null,null,null,* from log where userid is null;
2)null值加随机数,这样null就不会都被分到一个reducetask中
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)关联键字段类型不一致
原因:
例如两个表连接,关联字段一个是int类型一个是string类型,会强制将string类型转换为int类型,但是有的转换不了,这样就会转化为空值,又变成了大量空值造成数据倾斜
解决方案:
将字段类型统一
select * from user a left outer join log b on b.user_id = cast(a.user_id as string);
3)大小表关联产生数据倾斜
这里怎么理解大表还是小表:hive.mapjoin.smalltable.filesize=25000000//23.8M系统默认的小表大小,因为表的大小于23.8M,join就是mapjoin,一旦表的大小超过23.8M就是reducejoin;
①小表和大表连接
当小表的大小下雨23.8M的时候,join执行的是mapjoin,不会产生数据倾斜;
②中表和大表连接
当一张表的大小超过23.8M,但是数据量不是特别大的时候,可以称之为中表,这时候如果硬件物理内存足够,可以强制进行mapjoin,这样就可以避免数据倾斜
MapJoin 具体用法:
select /* +mapjoin(a) */ a.id aid, name, age from a join b on a.id = b.id;
select /* +mapjoin(movies) */ a.title, b.rating from movies a join ratings b on a.movieid =
b.movieid;
还可以通过hive参数的配置来解决什么时候是mapjoin
set hive.auto.convert.join=true;
//设置 MapJoin 优化自动开启
set hive.mapjoin.smalltable.filesize=25000000
//设置小表不超过多大时开启 mapjoin 优化
③大表和大表连接
解决方式一:
将两个大表切分为小表,分别再mapjoin;
解决方式二:
瘦身,通过过滤掉表中业务需求用不到的东西从而达到瘦身的目的;
例如:有日志表log和用户表user;其中要查询活跃的用户的日志信息,可以通过日志表达到对用户表的过滤,有日志信息的用户才是活跃用户;
①求出log表中的独立用户
select distinct user_id
from log;
②对user表进行过滤,只要log表中存在的用户
select /*+mapjoin(b)*/
a*
from user a join
(select distinct user_id
from log)b on
a.user_id =b.user_id;
③真正的连接
select *
from
(select /*+mapjoin(b)*/
a*
from user a join
(select distinct user_id
from log)b on
a.user_id =b.user_id) c join log d on c.user_id=d.user_id;
最后
以上就是忐忑钢笔为你收集整理的Hive--数据倾斜以及解决方案的全部内容,希望文章能够帮你解决Hive--数据倾斜以及解决方案所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复