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 优化