https://www.cnblogs.com/ggjucheng/archive/2013/01/03/2842860.html
1.数据倾斜产生原因
数据分配不均匀,导致某些reduce分区的数据量太多,job的执行一直卡在这几个reduce。
产生原因:
1.key值分布不均匀
2.数据本身特性
3.某些hql语句本身存在数据倾斜
2.数据倾斜的具体表现
任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。因为其处理的数据量和其他reduce差异过大。
单一reduce的记录数与平均记录数差异过大,通常可能达到3倍甚至更多。 最长时长远大于平均时长。
3.不容易产生数据倾斜的语句
1.直接fetch
select * from ... where ... limit n ;
2.聚合函数和group by 一起使用
4.容易产生数据倾斜的语句
1.reducejoin
2.聚合函数不和group by一起用 只有一个reducetask
3.count(distinct ) 只有一个reducetask
4.join时null值过多,所有的null值在一个分区进行处理 ,解决思路:null值不关联或者null+random 进行随机hash
5. join时数据类型不一致导致关联不上,例如:用户表中user_id字段为int,log表中user_id字段既有string类型也有int类型。当按照user_id进行两个表的Join操作时,默认的Hash操作会按int型的id来进行分配,这样会导致所有string类型id的记录都分配到一个Reducer中。
5.数据倾斜时的优化
1.hive.map.aggr=true; 开启combiner,在map的输出端进行局部聚合
2.hive.groupby.skewindata=true;
在group by时进行负载均衡,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。
3.大小表关联时,开启mapjoin