MapReduce是一种编程模型,编写很少的代码就可以实现很强大的计算功能。它主要体现了分治思想,就是把一个大问题分成相同的一些小问题,最后将小问题的结果汇总起来。
这里我是用一个数扑克牌的问题来帮助自己理解的。比如一副不完整的扑克牌(可能重复),要求数出每种花色的个数,假如我们交给四个人去做。
Map:负责处理小问题,并输出小结果。将扑克牌分给四个人,每个人将自己手里的牌按照某种花色顺序排好,一张张的放到桌面上,可以说有几张牌输出就是几份。这里假如有两张相同的红桃A,输出结果也是红桃A:1 红桃A:1 而不是红桃A:2
Reduce:负责汇总所有的小结果,形成最终的结果。将所有人的红桃拿来,计算;再将所有人的黑桃拿来,计算;以此类推,即可算最终结果。这里拿来的值应该是红桃A:{1,1,1,1,1...} 值是数组
除了这两个角色,mapreduce中还有其他的角色,比如combiner、partition、shuffle。
combiner(组合器):负责将自身map的结果进行一次reduce,它的本质就是reduce,只不过计算的阶段不一样。就像每个人再放到桌面时,不再是一张张的放,而是先自己算好每种花色的个数,将相同花色放在一个牌堆,这样每个人的输出最多只会有四份。这个角色不是必要的,需要根据具体业务来决定。只有combiner的计算操作不会影响最终结果时才可以。使用了combiner,遇到相同的牌时,红桃A:1 红桃A:1经过combiner计算后输出应该是红桃A:2,这样在reduce时值会是这里拿来的值应该是红桃A:{2,1,1,2} 数组长度最多为4,因为每一个map都计算好了自己的红桃A数量。
partition(分割器):上面的例子,最终结果的汇总(reduce)是由一个人来完成的。假如我现在要求根据不同的牌值来输出给不同的文件,就要用上partition了。它默认根据key的hash值%reduce的个数,来算出每个结果交给哪个reduce去做,并保证了不同reduce计算的时候不会重复计算某个值。比如我们假设,使用默认的HashPartitioner,扑克牌的hash值就是它的牌面,现在有3个人去进行reduce,那么在map的过程中,每个人会将自己的A、4、7、10、K; 2、5、8、J; 3、6、9、Q所分成的花色牌分三堆放在一起,(在没有使用combiner的情况下,最多分出三大堆,自己牌数的小堆;使用了combiner的情况下,最多分出三大堆,每个大堆里有四个小堆(红黑花片))。 这样在reduce的过程中,三个人每个人去取一堆,分别计算输出,就达到了根据值来输出不同结果文件的目的。