一、MapTask过程
MapTask阶段主要是分为read
-Map
-Collect
-Spill
四个过程
Read
阶段:MapTask通过用户编写的RecordReader
,从输入InputSplit
中解析出一个个Key/Value
对。Map
阶段:将解析出来的Key-value
交给map()
方法进行处理,产生新的Key-Value
对。Collect
阶段:map()
处理完数据以后会调用OutputCollector.collect()
输出结果。该函数,将这些键值对进行分区,然后写入环形缓冲区。Spill
阶段:环形缓冲区写到80%以后,会将缓冲区的数据写到本地磁盘,生成一个临时文件。刷写前会对数据进行一次排序,有需要的话,还可以做归并和压缩等操作。- 使用快速排序算法对环形缓冲区的数据进行排序,排序方式是:先按照分区号进行排序,然后按照键值对中的
Key
进行排序。经过这样的排序以后,数据以分区为单位聚集在一起,相同分区中的键值对按照key
有序。 - 按照分区编号由小到大将每个分区中的数据写入临时目录下的临时文件:
output/sillN.out
(N是Spill的次数)。如果用户设置了combiner
,则写入文件前还会对数据进行一次聚合操作。 - 将分区数据的元数据写入内存索引文件SpillRecod中,元数据包括:在临时文件中的偏移量、压缩前数据的大小,压缩后数据的大小。如果内存索引文件大于1M,则会将内存中的索引文件写入本地文件:
output/spillN.out.index
。
- 使用快速排序算法对环形缓冲区的数据进行排序,排序方式是:先按照分区号进行排序,然后按照键值对中的
Combiner
阶段:当所有数据处理完成以后,MapTask
会将临时文件合并成一个大文件,并保存到ouput/file.out
,同时保存相应的索引文件output/file.out.index
。文件合并过程中是以分区为单位进行合并。最后让每个MapTask
阶段只生成一个数据文件。
二、RecudeTask过程
reduceTask
阶段:copy
-merge
-sort
-reduce
Copy
阶段:ReduceTask
从每个MapTask
远程拷贝一片数据,如果超过阈值,则将文件写到本地磁盘,否者直接放在内存中。Merge
阶段:拷贝数据的同时,ReduceTask
启动了两个线程对内存和磁盘上的数据进行了合并,以防止内存使用过多或者磁盘上的文件过多。Sort
阶段:按照用户编写的MapReduce
程序,reduce()
程序的输入是按key聚集的一组数据。为了让相同的key聚集在一起,ReduceTask
对从各个分区拿过来的数据进行一次归并排序(原来的数据本身就局部有序)。Reduce
阶段:reduce()
函数将结果写入HDFS。
三、 Shuffle过程
什么是Shuffle
阶段,Shuffle
阶段位于map()
之后,reduce()
之前。
Map
方法之后,数据首先进入到分区方法,把数据标记好分区,然后把数据发送到环形缓冲区;环形缓冲区默认大小100m,环形缓冲区达到80%时,进行溢写;溢写前对数据进行排序,排序按照对key的索引进行字典顺序排序,排序的手段「快排」。- 溢写产生大量溢写文件,需要对溢写文件进行「归并排序」。
- 对溢写的文件也可以进行
Combiner
操作,前提是汇总操作,求平均值不行。最后将文件按照分区存储到磁盘,等待Reduce
端拉取。 - 每个
Reduce
拉取Map
端对应分区的数据。拉取数据后先存储到内存中,内存不够了,再存储到磁盘。 - 拉取完所有数据后,采用归并排序将内存和磁盘中的数据都进行排序。在进入Reduce方法前,可以对数据进行分组操作。
这几个过程有些细节还不熟悉,继续加强!!!