整个MapReduce的过程大致分为 Map --> Combine --> Reduce(先Shuffle) 三个部分。
Input and Output types of a MapReduce job:
(input) <k1, v1> -> map -> <k2, v2> -> combine -> <k2, v2> -> reduce -> <k3, v3> (output)
mapreduce实际的处理过程可以理解为Input->Map->Sort->Combine->Partition->Reduce->Output。
例如输入为两行的文本:
Hello World Bye World
Hello Hadoop Goodbye Hadoop
1)Input阶段,通过InputFormat接口从HDFS中读取数据,每一行解析成一个<k,v>,然后输入到map中。
<0, Hello World Bye World> , <1, Hello Hadoop Goodbye Hadoop>
2)Map阶段,对输入的(key,value)对进行处理,生成新的<Key, Value>。
对于示例中的第一行输入,map过程输出是:
< Hello, 1>
< World, 1>
< Bye, 1>
< World, 1>
对第二行输入,map过程输出是:
< Hello, 1>
< Hadoop, 1>
< Goodbye, 1>
< Hadoop, 1>
Map进程中有一个环形内存缓冲区用于处理数据,默认是100M,当内存中的数据达到80M时,后台就开启一个进程,锁住80M的空间,将数据写入剩余的20M空间,同时将80M的数据溢出(spill)到磁盘。当数据从内存缓存区往磁盘中写时,会生成很多小的spill文件,每个文件会分为好几个区,每个分区中的文件使用快速排序算法按照key值进行排序。
3)Sort操作,得到map方法输出的<key,value>对后,Mapper会将它们先按照分区编号,然后按照key值进行排序,使用快速排序算法。排序后,同一分区内的数据按key有序。默认分为一个区,可以指定,假设有2个分区:
<Bye, 1>, <Hello, 1>, <World, 1>, <World, 1> 和
<Goodbye, 1>, <Hadoop, 1>, <Hadoop, 1>, <Hello, 1>
4)Combine操作,是可选的。主要是在map计算出中间文件前做一个简单的合并重复key值的操作。
例如我们对文件里的单词频率做统计,map计算时候如果碰到一个hadoop的单词就会记录为1,但是这篇文章里hadoop可能会出现n多次,那么map输出文件冗余就会很多,因此在reduce计算前对相同的key做一个合并操作,那么文件会变小,这样就提高了宽带的传输效率,毕竟hadoop计算力宽带资源往往是计算的瓶颈也是最为宝贵的资源,但是combiner操作是有风险的,使用它的原则是combiner的输入不会影响到reduce计算的最终输入,例如:如果计算只是求总数,最大值,最小值可以使用combiner,但是做平均值计算使用combiner的话,最终的reduce计算结果就会出错。
combiner其实也是一种reduce操作,不过是本地化的reduce操作。
5)Partitioner操作
每次spill操作也就是写入磁盘操作时候就会写一个溢出文件,也就是说在做map输出有几次spill就会产生多少个溢出文件,等map输出全部做完后,map会合并这些输出文件,使每个Mapper只生成一个输出的数据文件。
这个过程里还会有一个Partitioner操作,对于这个操作很多人都很迷惑,其实Partitioner操作和map阶段的输入分片(Input split)很像,一个Partitioner对应一个reduce作业,如果我们mapreduce操作只有一个reduce操作,那么Partitioner就只有一个。
------------------------
6) Reduce阶段
Reducer有3个主要阶段:shuffle、sort和reduce。
Shuffle 多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点上。将spill文件中的分区往相应的reduce任务发送,例如partition0发送往reduce0,partition1发送往reduce1,partition2发送往reduce2,以此类推。Reducer将来自不同map端的同一个分区文件归并成一个大的文件。
Reducer先对从Mapper接收的数据进行排序,再交由用户自定义的reduce方法进行处理,得到新的<key,value>数据。
7)Output操作
示例中的输出结果为:
< Bye, 1>
< Goodbye, 1>
< Hadoop, 2>
< Hello, 2>
< World, 2>
Reducer的结果写入到HDFS中。
图1:MapReduce的内部逻辑
![Map Task](https://i-blog.csdnimg.cn/blog_migrate/9aa24f2f3555fb2c4c830c005f525b6f.png)
![Reduce Task](https://i-blog.csdnimg.cn/blog_migrate/87c23ef35ffe3760fe52d9585611d86e.png)
参考:
https://zhuanlan.zhihu.com/p/42864264
https://www.cnblogs.com/ahu-lichang/p/6645074.html
图示:https://www.cnblogs.com/codeOfLife/p/5410423.html