hive数据倾斜

580 阅读2分钟

数据倾斜原因:

key分布不均,或者业务数据本身的特性,和sql语句本身就有数据倾斜,建表不规范的问题

例如:

1.大小表join,其中小表key集中 ,分发到某个或几个reduce上的数据远高于平均值

2.大表join大表,有特殊值比如0和空值过多 ,这些空值都有一个reduce处理非常慢

3.group by 维度过小,某值过多,处理某值的reduce耗时

4.count(distinct) 某特殊值过多,处理此特殊值耗时

表现:

某个reduce任务长时间在99%和100%,与其他reduce数据量差异很大,job数多

解决方法:

1.sql语句做列裁剪,使两表join数据量相对变少

2.group by维度过小

hive.map.aggr=true; --map端部分聚合
hive.groupby.skewindata=true; --数据倾斜时,负载均衡,生成两个 MR JOB

3.大小表join,走map join 小表数据比较小走内存 自动开启map join

set hive.auto.convert.join=true;
set hive.mapjoin.smalltable.filesize=25000000; --即25M

4.大表join大表把空值变成字符串加上随机数,把数据分发到不同reduce上

例如:

nvl(字段,concat('hive',rand()))

5.count(distinct xx)有大量特殊值 可以采用先去重 sum() group by 替换count(distinct)

6.不同类型关联产生的数据倾斜,比如int和string把数据类型转换成字符类型 case(字段 string)

7.合并小文件

set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; --执行Map前进行小文件合并

输出端:通过输出端小文件合并,减少产生的小文件数量。 --mapd端

set hive.merge.mapfiles=true;

设置:启用小文件合并 - Map-Only作业,默认true; --reduce端

set hive.merge.mapredfiles=true;

设置:启用小文件合并 - Map-Reduce作业,默认false;

hive.merge.size.per.task=268534456

8.减少job数,设置合理的map ,reduce 的task数

数据倾斜主要就是设置合理的map,reduce的task数,将大量数据均匀分发到reduce上。