1.hive为什么会生数据倾斜
(1)不同数据类型关联产生数据倾斜
如:用户表中user_id字段为int,log表中user_id字段为string类型,当按照user_id进行两个表的join操作时。解决方式是:把数字类型转换成字符串类型
select * from users a
left outer join logs b
on a.user_id=cast(b.user_id as string)
(2)空值产生的数据倾斜的问题
生产环境中经常会有大量空值数据进入到一个reduce中去,导致数据倾斜。
场景:如日志中常会有信息丢失的问题,如日志中的user-id,如果取其中的user-id和用户表中的user-id关联,会碰到数据倾斜
解决1:user-id为空的不参与关联
select * from log a
join users b
on a.user-id is not null
and a.user-id=b.user-id
union all
select * from log a
where a.user-id is null;
解决2:赋予空值新的key值
select * from log a
left outer join users b
on
case when a.user-id is null then concat('hive',rand())
else a.user-id end =b.user-id;
方法2比方法1效率更好,不但io少了,而且作业数也少了。在方法1中,log读取2次,jobs是2。放法2中job是1。这个优化适合无效id(如 -99,‘’,nu'l'l)等产生的倾斜问题。把空值的key编程一个字符串加上随机数,就能把倾斜的数据分到不同的reduce上,解决数据倾斜的问题。
2.解决数据倾斜
(1)group by
group by 优于distinct group
解决:采用sum()group by 的方式来代替count (distinct)完成计算
(2)开启数据倾斜时负载均衡
set hive.group by.skewindata = true
(3)map join
(4)设置多个reduce数
1、对于join,在判断小表不大于1G的情况下,使用map join
2、对于group by或distinct,设定 hive.groupby.skewindata=true
3、尽量使用上述的SQL语句调节进行优化