Hive 数据倾斜

http://www.cnblogs.com/qingyunzong/p/8847597.html
http://www.cnblogs.com/qingyunzong/p/8847775.html

空值产生数据倾斜的原因:

应该是 空值 被看做一个值,导致数据倾斜

过滤空值,或者为空值赋予一个随机值即可。

count(distinct) 产生数据倾斜的原因:

作业运行时的Reduce Task个数为1。
尝试显式地增大Reduce Task个数来提高Reduce阶段的并发,使每一个Reduce Task的数据处理量控制在2G左右。具体设置如下:

set mapred.reduce.tasks=100

调整后发现这一参数并没有影响实际Reduce Task个数,还是 1...
原来Hive在处理 COUNT 这种 “全聚合” 计算时,它会忽略用户指定的 Reduce Task数,而强制使用1。

使用 count() 结合 group by 的方式即可。

不同数据类型产生数据倾斜

用户表中 user_id 字段为 int,log 表中 user_id 为既有 string 也有 int 的类型, 当按照两个表的 user_id 进行 join 操作的时候,默认的 hash 操作会按照 int 类型的 id 进 行分配,这样就会导致所有的 string 类型的 id 就被分到同一个 reducer 当中

把数字类型 id 转换成 string 类型的 id 即可。

大小表关联查询产生数据倾斜

使用map join解决小表关联大表造成的数据倾斜问题。

以大表 a 和小表 b 为例,所有的 maptask 节点都装载小表 b 的所有数据,就省去了 reduce 做汇总的过程。
在内存允许的条件下使用 map join 效率高些,这只限于做 join 查询的时候。

在 hive 中,直接提供了能够在 HQL 语句指定该次查询使用 map join,map join 的用法是 在查询/子查询的SELECT关键字后面添加/*+ MAPJOIN(tablelist) */提示优化器转化为map join(早期的 Hive 版本的优化器是不能自动优化 map join 的)。其中 tablelist 可以是一个 表,或以逗号连接的表的列表。tablelist 中的表将会读入内存,通常应该是将小表写在 这里。

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;

在 hive0.11 版本以后会自动开启 map join 优化,由两个参数控制:

set hive.auto.convert.join=true; //设置 MapJoin 优化自动开启

set hive.mapjoin.smalltable.filesize=25000000 //设置小表不超过多大时开启 mapjoin 优化

你可能感兴趣的:(Hive 数据倾斜)