MapReduce组件功能分析

版权声明:本文为博主原创文章,未经博主允许不得转载。http://blog.csdn.net/aspirinvagrant https://blog.csdn.net/fenghuangdesire/article/details/20378693
		

JobClient

每一个job 都会在客户端通过JobClient类将应用程序以及作业的配置参数打包成jar文件存储在HDFS,并把作业提交给 JobTracker
JobClient.runJob()创建一个新的 JobClient实例,调用其submitJob()函数。
JobClient将作业提交给JobTracker之前,需要进行一些初始化工作,由JobClient.subnitJobInternal(job)完成,包括:(1)JobTracker请求一个新的 job ID;(2)检测 joboutput 配置;(3)计算 jobinput splits;(4)Job运行所需的资源上传到JobTracker的文件系统(HDFS)中的文件夹中,包括 job jar文件,job.xml 配置文件。这些 MapReduce文件的上传以及下载是有 Hadoop数据分发工具DistributedCache完成
 

JobTracker

JobTracker是一个master服务,主要完成作业的控制和资源的管理。作业的控制主要包括作业的分解和状态的监控,作业的监控是由三层树状结构表示,自顶向下为JobInProgress、TaskInProgress和Task Attempt。资源的管理主要包括资源的表示和分配,MRv1基于slot表示资源,MRv2基于Linux Container表示资源,资源的分配是由TaskScheduler完成,即JobClient通过RPC调用的方法submitJob,会为该作业创建JobInProgress对象,用于追踪正在运行作业的状态和进度,并通知TaskScheduler初始化作业,默认为JobQueueTaskScheduler,也即按照 FIFO的方式调度任务,然后TaskScheduler将任务列表分配给TaskTracker。

TaskTracker

TaskTracker是运行于多个节点上的slave服务,主要完成向JobTracker汇报心跳和执行JobTracker的命令。汇报心跳的信息包括结点状态、资源使用情况、任务的执行进度、任务的运行状态以及Counter值。JobTracker收到TaskTracker汇报的心跳信息后,根据这些信息以及作业的运行状况给TaskTracker下达命令,包括LaunchTaskAction、CommitTaskAction、KillTaskAction、KillJobAction和TaskTrackerReinitAction。
TaskTracker主动与JobTracker通信,接收作业并负责直接执行每一个任务。TaskTracker作为一个单独的JVM来运行,TaskTracker周期性的向JobTracker发送heartbeat。在heartbeat中,TaskTracker告知JobTracker其已经准备运行一个新的taskJobTracker 将分配给其一个task
TaskTracker被分配了一个task,下面便要运行此task首先,TaskTracker将此jobjar从共享文件系统中拷贝到TaskTracker的文件系统HDFS中。TaskTrackerDistributedCache 中将job运行所需要的文件拷贝到本地磁盘。其次,其为每个task创建一个本地的工作目录,将jar解压缩到文件目录中。其三,TaskRunner创建一个新的JVM来运行task 

Map过程

Map Taskinput split 中读取一个个的 record,然后依次调用Mapper map函数,将结果写入缓存memory buffer。当 buffer中数据的到达一定的大小,一个后台线程 SpillThread将数据开始写入硬盘。在写入硬盘之前,将 buffer中的数据通过Partitioner分成多个 partitionPartitioner接口根据key或value及reduce的数量来决定当前的key/value对最终应该交由哪个reduce task处理。在同一个 partition中,SpillThread 线程会将数据按照 key在内存中排序。每次从内存向硬盘 flush数据,都生成一个新的spill文件。当此 task结束之前,所有的spill文件被合并为一个整的被 partition的而且排好序的文件。reducer可以通过 http协议请求map 的输出文件, tracker.http.threads可以设置http 服务线程数。

Reduce过程

Reduce Task同时启动多个MapOutputCopier线程,从 schedulerCopies列表中获取Map Task 的输出位置,通过 Http Get从各个Map Task 上远程拷贝数据,先写入内存,其大小超过一定阈值,这时写入磁盘。与此同时, Reduce Task启动LocalFSMerger InMemFSMergerThread两个线程分别对磁盘和内存中的数据进行合并。当所有的 map输出都拷贝到Reduce Task后,进入sort过程,将所有的map输出合并为大的排好序的文件。最后进入reduce过程,调用reducer reduce函数,处理排好序的输出的每个 key,最后的结果写入HDFS


Shuffle过程

  shuffle位于Map过程和Reduce过程之间,下面从map端和reduce端分别介绍。
map端:
1、在map task执行时,读取split,经过mapper的运行后,输出key/value对,将key/value对写入内存缓冲区中,减少磁盘IO的影响。key/value对以及Partition的结果都会被写入缓冲区。写入之前,key与value值都会被序列化成字节数组;
2、内存缓冲区是有大小限制的,默认是100MB,在一定条件下将缓冲区中的数据临时Spill(溢写)到磁盘,然后重新利用这块缓冲区。溢写是由单独线程来完成,不影响往缓冲区写map结果的线程。整个缓冲区溢写的比例spill.percent,默认0.8,溢写线程启动,锁定这80MB的内存,执行溢写过程。Map task的输出结果还可以往剩下的20MB内存中写。 溢写线程启动后,需要对这80MB空间内的key做排序(Sort)。写到磁盘中的溢写文件是对不同的reduce端的数值做过合并(combine)。
3、每次溢写会在磁盘上生成一个溢写文件,当map task完成时,内存缓冲区中的数据也全部溢写到磁盘中形成一个溢写文件,最后将所有溢写文件归并到一起(Merge)。

reduce端:
map端的所有工作都已结束,每个reduce task不断地通过RPC从JobTracker那里获取map task是否完成的信息,如果reduce task得到通知,获知某台TaskTracker上的map task执行完成,Shuffle的后半段过程开始启动。 
1、Copy过程。Reduce进程启动一些数据copy线程、,通过HTTP方式请求map task所在的TaskTracker获取map task的输出文件。
2、Merge阶段。Copy过来的数据会先放入内存缓冲区中,这里的缓冲区大小要比map端的更为灵活,它基于JVM的heap size设置,因为Shuffle阶段Reducer不运行,所以应该把绝大部分的内存都给Shuffle用。当内存中的数据量到达一定阈值,就启动内存到磁盘的merge。与map端类似,进行溢写和合并(执行Combiner),然后在磁盘中生成了多个的溢写文件。内存到磁盘的merge一直在运行,直到没有map端的数据时才结束,然后启动磁盘到磁盘的merge方式生成最终的Reducer的输入文件。
3、Reducer的输入文件。当Reducer的输入文件已定,整个Shuffle才最终结束。然后就是Reducer执行,把结果放到HDFS上。 



猜你喜欢

转载自blog.csdn.net/fenghuangdesire/article/details/20378693