可以提前在map阶段进行combine,以减少传输的数据量。
在mapper加上combine相当于提前进行reduce,就是把一个mapper中相同的key进行聚合,以减少shuffle(洗牌)过程中传输的数据量,以及reducer阶段的计算量。但是如果导致数据倾斜的key大量分布在不同的mapper阶段的时候,这个方法就不是很实用了。
导致数据倾斜的key大量分布在不同的mapper时。
1 可以使用局部聚合加全局聚合
即在第一次map阶段对那些导致数据倾斜的key加上1-n的随机前缀,这样本来相同的key也会被分配到多个reducer中进行局部聚合,这样数据量就会大大降低。
在第二次MapReduce时去掉key的随机前缀,进行全局聚合。采用的思想就是两次MapReduce,第一次将key随机散列到不同的reducer中经常处理以达到负载均衡的目的,第二次再根据去掉key的随机前缀,按照原来的key进行reduce处理。但是这个方法采用了两次MapReduce,性能方面比较差。
2 增加reducer,提高并行度。方法:JobConf.setReduceTasks(int)
3 实现自定义分区。根据数据分布的情况来自定义散列函数,将key均匀的分配到不同的reducer。