剖析MapReduce过程

Job初始化

当JobTracker接收到一个请求调用它的submitJob()方法时,它把该请求插入一个内部队列中,由job的调度管理器进行调度并初始化。Job初始化将会创建一个控制job的执行情况的对象RunningJob,RunningJob会对tasks进行压缩,记录tasks的信息用于跟踪tasks的状态和执行进度。

<wbr></wbr>

为了能够使得tasks运行起来,job的调度管理器首先会接收来自共享文本系统的分片,分片通过调用JobClient产生,然后调度管理器会为每一个分片创建一个map task,而reduce rasks的创建由JobConf中的mapred.reduce.tasks属性决定,通过setNumReduceTasks()方法设置。而Job的调度管理器只是简单的创建reduce tasks的数量。此时Tasks获得ID。

<wbr></wbr>

剖析MapReduce过程_第1张图片

Figure 1:How Hadoop run a MapReduce job

<wbr></wbr>

<wbr></wbr>

分配Task

TaskTrackers执行一个简单的循环,周期性地向JobTracker发送心跳查询。心跳查询告诉jobtracker有一个tasktracker处于活跃中,心跳查询还可以作信息传输通道。作为心跳查询的一部分,一个tasktracker会表明是否有一个新的task准备就绪,如果是,jobtracker将会通过心跳查询的返回值向该tasktracker分配一个task。

<wbr></wbr>

在选择一个task分配给tasktracker前,jobtracker必须选择一个job用于选择task。MapReduce中有多种调度算法,默认的优先队列调度算法。选择job后,现在jobtracker为job选择一个task。

<wbr></wbr>

TaskTracker有固定的槽用于运行map tasks和reduce tasks。比如,一个tasktracker可能同时运行两个map tasks和两个reduce tasks(具体的数量取决于tasktracker上处理器的个数和内存的容量)。默认的调度管理器会先填充map task槽(slot),因此,如果tasktracker中至少有一个map task槽,jobtracker将会选择一个map task;否则选择一个reduce task。

<wbr></wbr>

在选择reduce task时,jobtracker只是简单地从任务列表中取出下一个还没有被执行的reduce task,因为这时不需要考虑数据局部性。而对于一个map task,需要充分考虑tasktracker的网络位置,并选择一个输入分片尽可能靠近tasktracker的task。在优化情况下,task是data-local的,都在分片所属的同一个集群节点上运行。另外一种情况是,task是rack-local的:在相同的rack上,而不是相同的节点(分片同样也是)。一些tasks既不属于data-local,也不属于rack-local,它们从一个不同的rack中获取数据,而这个rack来自于它们所在的rack。

<wbr></wbr>

<wbr></wbr>

执行Task

现在tasktracker已分得一个任务,下一步就是执行这个任务。首先,tasktracker从共享文件系统中复制job JAR到tasktracker的文件系统,还得从分布式缓冲(distributed cache)中复制一些必须的文件到本地;然后在本地为该任务创建一个工作空间,解压JAR文件到该工作空间;最后,实例化TaskRunner,执行任务。

<wbr></wbr>

TaskTracker启动一个新的Java Virtual Machine,每一个任务都在里面运行。因此,任何由用户自定义的map和reduce方法引发的bug都不会影响到tasktracker。Tasks之间可能重用JVM。

<wbr></wbr>

子进程通过脐带接口(umbilical interface)与父进程通信,通过这种途径,子进程每个几秒钟就向父进程报告任务的进度,直到任务结束。

<wbr></wbr>

<wbr></wbr>

流和管道(Streaming and Pipes)

流和管道都是执行特定的map和reduce tasks,为了启动用户支持的可执行文件并与之通信。

<wbr></wbr>

使用Streaming时,Streaming task通过标准输入输出流与进程(可能使用任何语言编写)通信;而在使用Pipes时,建立socket接口与进程通信,因此在启动的时候,C++进程建立一个持久的socket连接到父级Java Pipes task。

<wbr></wbr>

不管是使用Streaming还是Pipes,在执行task的期间,Java进程将传递输入的key/value对到外部进程,该外部进程通过用户自定义的map或reduce方法运行,并将输出的key/value对返回Java进程。从tasktracker的角度来看,就好像是它的子进程执行map或reduce。

<wbr></wbr>

剖析MapReduce过程_第2张图片

Figure 2:The relationship of the Streaming and Pipes executable to the tasktracker and it child

<wbr></wbr>

<wbr></wbr>

进度与状态更新

MapReduce作业是长时间运行的批量作业,可能需要几分钟到几小时不定的时间运行,因此需要将作业的进度反馈给用户。作业和它的任务都有一个状态信息,包括作业或任务的执行状态(e.g.,running,successfully completed,failed),maps和reduces的进度,作业counters的值,状态信息及描述。这些信息在job的执行过程中不断地变化,那么它是怎样反馈给客户端的呢?

<wbr></wbr>

当一个task运行时,它跟踪它的进度。对于map tasks,指的是输入执行的百分比;对于reduce tasks,有一点复杂,但系统还是能够估算reduce输入执行的进度:系统将所有的进度分成三部分,分别对应于shuffle的三部分。举个例子,如果task已经进行了reducer输入的一半,那么task的进度为5/6,这时因为task已经完成了copy和sort过程(各1/3),并且进行到reduce过程的一半(1/6)。

<wbr></wbr>

在MapReduce中进度由什么构成?

<wbr></wbr>

并不是所有的进度都能测量的,但是不管怎样,进度告诉Hadoop存在一个task正在运行。比如,一个任务写输入记录就是正在构成进度,虽然它或许不能用准确的百分比来描述,因为后面有些设置我们还不知道。

<wbr></wbr>

报告进度非常重要,它代表着Hadoop不会将一个正在运行的task标志位FAILED。下面是所有能产生进度的操作:

l<wbr> 读输入记录(在mapper或reducer中)</wbr>

l<wbr> 写输出记录(在mapper或reducer中)</wbr>

l<wbr> 在reporter中设置状态描述(使用Reporter的setStatus()方法)</wbr>

l<wbr> 计数器增量(使用Reporter的incrCounter()方法)</wbr>

l<wbr> 调用Reporter的process()方法</wbr>

<wbr></wbr>

Tasks也有一组计数器用于统计在task运行时发生的一些事件,一些计数器是框架内置的,比如统计输出记录数量的计数器,而一些是由用户自定义的。

<wbr></wbr>

如果一个task报告进度,它会设置一个标签,表明当状态发生变化时通知tasktracker。每隔三秒钟,该标签会在一个分离的线程中被检测一次。如果设置了该标签,它会通知tasktracker当前task状态。与此同时,tasktracker每五秒钟向jobtracker发送心跳查询(5秒是最小值,心跳查询的间隔取决于集群规模:集群规模越大,间隔越大。)所有在jobtracker中将被tasktracker执行的tasks的状态,都会随心跳包发送出去。发送Counters没有这般频繁,因为它们可以走高带宽。

<wbr></wbr>

JobTracker汇集起所有这些更新信息,从全局来监控这些jobs和tasks的状态。最后,JobClient接受最新的状态信息,客户端还可以通过JobClient的getJob()方法来获得一个RunningJob实例,该实例包含一个Job的所有状态信息。

<wbr></wbr>

<wbr></wbr>

作业结束

当jobtracker接收到通知说,这次作业的最后一个task已经完成,它会将job的状态改为“successful”。当JobClient获取到作业的状态时,它知道job已经成功完成,然后JobClient打印信息告知用户作业已成功结束,最后从RunJob()方法返回。

<wbr></wbr>

用户可以通过job.end.notification.url属性设置jobtracker发送一个HTTP作业通告。

<wbr></wbr>

最后,jobtracker清除job的工作状态信息,并命令tasktracker也进行清除工作。

剖析MapReduce过程_第3张图片

Figure 3:How status updates are propagated through the MapReduce system

你可能感兴趣的:(mapreduce)