概念:数据倾斜是指,map /reduce程序执行时,reduce节点大部分执行完毕,但是
有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,这是因为某一
个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce
节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完。
执行操作:
1.其中一个表较小,但是key集中,可能会导致分发到一个或几个Reduce上的数据远高于平均值原因:
1.key分布不均4.某些语句本身就有数据倾斜
解决方案:有数据倾斜的时候进行负载均衡,当选项设定为 true,生成的查询计划会有两个 MR Job。
第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分
聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的
Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key
分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完
成最终的聚合操作。
2.如何join?关于驱动表的选取,选用join key分布最均匀的表做为驱动表。做好列裁剪和filter操作,
以达到两表做join的时候数据量相对变小的效果。
3.使用mapjoin让小的维度表先进内存。在map端完成reduce。
4.大表join大表时,把空值的key变成一个字符串加上随机数,把倾斜的数据随机分布到不同的reduce上,
由于null值关联不上,处理后并不影响最终结果。
5.count distinct时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,
在最后结果中加1。如果还有其它计算,需要进行group by,可以先将值为空的记录单独处理,再和其他
结果进行union。
6.采用sum() group by的方式来替换count(distinct )进行计算。
7.在业务逻辑优化效果不大的情况下,有些时候是可以将倾斜的数据单独拿出来处理,最后union回去。
8.对于控制产生的倾斜问题,解决方案1:为空的数据不参与关联;方案2:随机(rand())赋予空值新的key。
把空值的key变成一个字符串加上随机数,就能把倾斜的数据分到不同的reduce上,解决数据的倾斜问题。
9.不同数据类型关联产生数据倾斜,默认的Hash操作会按int型的id来分配reduce,这样会导致所有的String
类型数据分配到同一个reduce。
10.使用 mapjoin 解决小表(记录数少)关联大表的数据倾斜问题,这个方法使用的频率非常高,但如果小表
很大,大到map join会出现bug或异常,这时就需要特别的处理。
总之,优化时把握一个规则,单个作业最优不如整体优。
原文地址:http://blog.csdn.net/sunlei1980/article/details/46572701