天天看点

MapReduce执行流程解析

本文基于hadoop2.x,以wordcount为例解析MapReduce执行流程。

注:假设HDFS中有两个文件。分别为1.txt(150M),2.txt(100M)

1.Map阶段

步骤:

(1)hadoop扫描指定路径下的所有文件,本文指的是1.txt和2.txt,并将其进行逻辑切片(也可称为逻辑规划),每个切片被称为split。通常切片大小与block大小保持一致。本文中两个文件将被切分为三个部分,记为split1,split2,split3。

      注:

     <1>逻辑切片不是真的将文件切割成不同的部分,而是进行规划,没有实际操作。

     <2>切片大小为什么要和block大小保持一致?是否可以不一致?这个问题将在后续文章中详细解答。

(2)hadoop为每一个分片构建一个map任务,称为maptask,并由该任务运行用户程序。

(3)hadoop的TextInputFormat组件从HDFS将1.txt,2.txt一行一行读取,然后封装为key-value对,传入用户程序。

      注:

     <1>TextInputFormat组件每读取一行,就会封装一次key-value对,调用一次用户重写的map方法,然后执行context.write(k,v)将运算结果输出。

(4)如果程序中设置job.setNumReduceTask的值大于1,会将map的输出结果进行分组,称为partition。分组规则是按照公式:分组编号=key.hashCode/分组数。则每一个key-value对都会有一个分组编号。如果程序中未设置job.setNumReduceTask(默认为1),则该步骤省略。

(5)每次调用map计算所得到的结果将最终保存到本地磁盘(非HDFS),为了降低与磁盘之间的IO读写,结果会先被保存到内存缓冲区。当写入数据达到该内存缓冲区阈值时,则进行溢出操作,称为spill。溢出的数据会先进行快速排序,然后形成一个临时文件保存到磁盘中

 注:

     <1>该缓冲区被设置为100M。

     <2>关于溢出时机的问题,如果该缓冲区要到100M才溢出一次,则导致后续写入操作不得不等待。因此该内存缓冲区设置了“溢出比”这个概念,该内存缓冲区的溢出比为0.8,即当写入数据达到80M时溢出一次,同时写操作可以继续执行。

     <3>内存缓冲区不断进行写入-->溢出-->写入的操作,所以该缓冲区也被称为环形缓冲区。

(6)当整个maptask结束后,hadoop先对溢出的临时文件进行合并(merge),然后进行堆排序(字典序),最后将处理后的文件保存到磁盘。

2.Reduce阶段

步骤:

(1)将属于自己分区的数据拉取并执行排序

(2)排序之后将key相同的key-value对调用reduce方法

(3)通过TextOutputFormat将结果写入磁盘

注:后续将进一步完善,不喜勿喷,欢迎大神指点,谢谢。

继续阅读