Hive之数据倾斜
Hive之数据倾斜
第一节:简介
一、数据倾斜
数据倾斜:由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点。
大数据中不怕数据量大,怕数据倾斜。
hive的数据倾斜 --- mapreduce的数据倾斜。
二、主要表现形式
hive运行日志中
map 100% reduce 97%
map 100% reduce 97%
map 100% reduce 97%
map 100% reduce 97%
。。。。。。。
第二节:hive中不易数据倾斜场景
一、 不执行mapreduce
1、简介
hql语句---不执行mapreduce的
hive.fetch.task.conversion 决定的哪些语句不用执行mapreduce任务而是执行fetch的任务即数据抓取。
2、none
此属性禁用,所有的hql语句都要执行mr任务
3、minimal
在版本0.10.0 through 0.13.1时默认使用
select*, filter on partition columns (where and having clauses),limit only
select *,where过滤分区字段的时候,limit 直接执行fetch的,不执行mr任务的。
以上三种情况不用执行mapreduce
4、more
Select,filter, limit only (including tablesample, virtual columns)
select 表中的任意没有加工的原始字段
where 过滤
limit
以上三种情况不用执行mapreduce。
group by、join、order by、distinct等肯定走mapreduce的。
二、group by和聚合函数
max|min|sum + group by
默认在map端执行combiner在map端先执行一次聚合(combiner),reduce端接受的数据量少,不容易产生数据倾斜的。
三、mapjoin
在mapjoin的时候,有多个的maptask,不走reducetask,所以不会造成数据倾斜。
第三节:hive中容易数据倾斜场景
一、join
reducejoin的时候,如果里面的字段有一个是特别的多的话,会产生数据倾斜的问题。
二、group by
group by不和聚合函数一起使用的时候
三、count(distinct)
慎重使用,极易产生数据倾斜。
最终只会启动一个reducetask,无论手动设置几个reducetask任务,最终只运行一个。
优化:
把 count和distinct的需求分开
先求distinct
select distinct userId from weibo;
再求count
select count(*) from (select distinct userId from weibo)a;
最终转换为2个mapreduce任务。
四、注意
在hive中如果一个hql语句需要转换为多个job,下一个job需要依赖上一个job的,上一个job的结果不落磁盘,直接发送给下一个job,下一个job的maptask的个数由上一个job的输出的reducetask的个数决定的。
第四节:经典场景
一、关联键存在大量null值
1、简介
在join(大*大)的情况下
2、解决方案
(1)将null值删除
(2)需要null值
二、关联建类型不统一
1、简介
在join(大*大)情况下
用户表中 user_id 字段为 int,log 表中 user_id 为 string类型,当按照两个表的 user_id 进行 join 操作的时候,默认的 hash 操作会按照 int 类型的 id 进行分配,这样就会导致所有的 string 类型的 id 就被分到同一个 reducer 当中。
因为此时的分区算法是:分区字段.hash%分区个数,所以不能识别string类型的,因此他们会被分配到同一个的reducetask。
2、解决方案
cast(原始数据 as 需要转换的类型)
cast(age as bigint)
利用类型转换函数。
三、reducejoin可能产生数据倾斜
1、小*小、大*小
不会产生数据倾斜的。
默认执行的mapjoin
小表限制:
set hive.auto.convert.join=true;
//设置 MapJoin 优化自动开启
set hive.mapjoin.smalltable.filesize=25000000 25M
//设置小表的大小
关联的时候,较小表小于等于25000000byte的时候,默认执行mapjoin。
2、大*中
3、大*大