MapTask:
读取数据:①一个MapTask处理一片数据,需要InputFormat来读取切片中的数据
Map阶段: ②将数据读取为每一对Key-value,每一对Key-value都会经过map方法处理
收集阶段: ③ context.write(keyOut,valueOut)!先将已经write的key-value攒起来!
攒到一定数量,将这部分key-value溢写到磁盘
溢写阶段: ④ 主要是将key-value溢写到磁盘保存为一个临时文件
官方将MapTask分为两个阶段:
①Map: 从读取数据,到进入Map()处理,到收集
②Sort: 从收集后到溢写
ReduceTask:
官方将MapTask分为三个阶段:
①copy : 每个ReduceTask只负责处理一个分区,启动一个shuffle进程,从所有的MapTask中拷贝自己处理的
分区的内容
②sort: 将所有的MapTask分区的内容,进行合并(merge),保证合并后的数据是有序的,方便处理!
会对所有的数据进行排序(sort)。
③reduce : 进入reducer,对数据进行处理!
在进入reducer之前,会获取key的分组比较器!
使用分组比较器,对所有的key-value进行分组操作!有相同key的value会被分配到一组!
进入reducer方法进行处理,处理后,使用OutPutFormat将处理后的key-value写到一个文件中!
为了方便记忆,Map Task 可分解为Read,Map,Collect,Spill,Combine五个阶段,将Reduce Task 分解为Shuffle,Merge,Sort,Reduce和Write五个阶段。
在MapReduce计算框架中,一个应用程序被化成Map和Reduce两个计算阶段,它们分别由一个或者多个Map Task和Reduce Task组成。其中,每个Map Task处理输入数据集合中的一片数据(split),产生若干数据片段,并将之写到本地磁盘上,而Reduce Task 则从每个Map Task上远程拷贝一个数据片段,经分组聚集和规约后,将结果写到HDFS中。总体上看,Map Task与Reduce Task 之间的数据传输采用了pull模型。为了提高容错性,Map Task将中间计算结果存放到本地磁盘上,而Reduce Task则通过Http协议从各个MapTask端拉取(pull)相应的待处理数据。为了更好地支持大量Reduce Task并发从Map Task端拷贝数据,Hadoop采用了Netty作为高性能网络服务器。
对于map task而言,它的执行过程概述为:首先,通过用户提交的inputformat将对应的inputsplit解析成一系列key/value,并依此交给用户编写的map()函数处理;接着按照指定的partitioner对数据分片,以确定每个key/value将交给哪个reduce task处理;之后将数据交给用户定义的combiner进行一次本地规约(如果用户没有定义直接跳过);最后将处理结果保存到本地磁盘上。
对于reduce task而言,由于它的输入数据来自各个map task,因此首先需要通过http 请求从各个已经运行完成的map task上拷贝对应的数据分片,待所有数据拷贝完成后,在以key为关键字对所有数据进行排序,通过排序,key相同的记录聚集到一起形成若干分组,然后将每组数据交给用户编写的reduce()函数处理,并将数据结果直接写到hdfs上作为最终输出结果。
1.Map Task详细流程
1) Read阶段:Map Task通过InputFormat,从split中解析出一系列<key,value>.
2) Map阶段:将解析出的<key ,value>依次交给用户编写的map()函数处理,并产生一系列新的<key,value>
3) Collect阶段:在map函数中,当数据处理完成后,一般会调用OutputCollector.collect()输出结果,在该函数内部,它将<key,value>划分成若干个数据分片(通过调用Partitioner),并写入到一个环形内存缓冲区中。
4) Spill阶段:即“溢写”,当环形缓冲区满后,MapReduce将数据写到本地磁盘上,生成一个临时文件。需要注意的是,将数据写入到本地磁盘之前,先要对数据进行一次本地排序,并在必要时对数据进行合并,压缩等操作。
Map Task为何将处理结果写入本地磁盘?该问题实际上波爱护两层含义,即处理结果为何不写入内存,或者直接发送给Reduce Task?首先,Map Task不能讲数据写入内存,因为一个集群中可能会同时运行多个作业,而每个作业坑你分多批运行Map Task,显然,将结果直接写入内存会耗光机器的内存;其次,MapReduce采用的是懂得调度策略,这意味着。一开始只有Map Task执行,而Reduce Task则处于未调度状态,因此无法将MapTask计算结果直接发送给Reduce Task。将Map Task 写入本地磁盘,使得Reduce Task执行失败时可直接从磁盘上再次读取各个Map Task 的结果,而无需让所有Map Task重新执行。总之,Map Task 将处理结果写入本地磁盘主要目的是减少内存存储压力和容错。
5)Combine节点:当所有数据处理完成后,Map Task对所有临时文件进行一次合并,以确保最终只会生成一个数据文件。
每个Map Task为何最终只产生一个数据文件?如果每个Map Task 产生多个数据文件(比如每个Map Task为每个Reduce Task产出一个文件),则会生成大量中间小文件,这将大大降低文件读取性能,并严重影响系统扩展性(M个Map Task和R个Reduce Task可能产生M*R个小文件)
2.Reduce Task 详细流程
1)Shuffle阶段:也称为Copy阶段,Reduce Task从各个Map Task上远程拷贝一篇数据,并根据数据分片大小采取不同操作,如果其大小超过一定阀值,则写到磁盘上,否则,直接放到内存。
2)Merge阶段:在远程拷贝数据的同时,Reduce Task启动了两个后端线程对内存和磁盘上的文件进行合并,以防止内存使用量过多或磁盘上文件数据过多
3)Sort阶段:按照MapReduce语义,用户编写的reduce()函数输入数据是按key进行聚集的一组数据。为了将key相同的数据聚在一起,Hadoop采用了基于排序的策略,由于各个Map Task已经实现对自己的处理结果进行了局部排序,因此Reduce Task只需对所有数据进行一次归并排序即可。
4)Reduce阶段:在该阶段中,Reduce Task将每组数据一次交给用户编写的reduce()函数处理
5)Write阶段:将reduce()函数输出结果写到HDFS上