1.数据倾斜原因:
① key分布不均匀
② 业务数据本身的特性
③ 建表时考虑不周
④ 某些SQL语句本身就有数据倾斜
2.解决方案:
- 设置参数
set hive.map.aggr=true 这个配置项代表是否在map端进行聚合 - 如果数据量非常大时,group by 替换distinct;
采用sum() group by的方式来替换count(distinct)完成计算。
set hive.groupby.skwindata=true,决定 group by 操作是否支持倾斜数据 当选项设定为 true,生成的查询计划会有两个 MR Job; - 当遇到一个大表和一个小表进行join操作时
使用mapjoin 将小表加载到内存中 - 遇到需要进行join的但是关联字段有数据为空
方法1:id为空的不参与关联,加where限制条件
方法2:给空值分配随机的key值 - 不同数据类型关联产生数据倾斜
方法:把数字类型转换成字符串类型
如用户表user_id字段为int,log表中user_id字段既有string类型,又有int类型,当按照user_id进行量表join操作时,string类型的user_id,会放到一个reduce中,结果可能会造成数据倾斜。
select * from users a
left outer join logs b
on a.user_id =cast(b.user_id as string)
6.控制空值分布
在生产环境中经常会遇到大量空置数据进入到一个reduce中去,最终导致数据倾斜。
解决方法:自定义分区,将空的值转换为字符串加随机数或纯随机数,将因空值而造成的倾斜的数据分到多个ruduce中;