6.1.5 执行任务

TaskTracker申请到新的任务之后,就要在本地运行任务了。运行任务的第一步是将任务本地化(将任务运行所必需的数据、配置信息、程序代码从HDFS复制到TaskTracker本地,见图6-1的步骤⑧)。这主要是通过调用localizeJob()方法来完成的(此方法的具体代码并不复杂,不再列出)。这个方法主要通过下面几个步骤来完成任务的本地化:

1)将job.split复制到本地;

2)将job.jar复制到本地;

3)将job的配置信息写入job.xml;

4)创建本地任务目录,解压job.jar;

5)调用launchTaskForJob()方法发布任务(见图6-1的步骤⑨)。

任务本地化之后,就可以通过调用launchTaskForJob()真正启动起来。接下来launchTaskForJob()又会调用launchTask()方法启动任务。launchTask()方法的主要代码如下:


……

//创建Task本地运行目录

localizeTask(task);

if(this.taskStatus.getRunState()==TaskStatus.State.UNASSIGNED){

this.taskStatus.setRunState(TaskStatus.State.RUNNING);

}

//创建并启动TaskRunner

this.runner=task.createRunner(TaskTracker.this, this);

this.runner.start();

this.taskStatus.setStartTime(System.currentTimeMillis());

……


从代码中可以看出launchTask()方法会先为任务创建本地目录,然后启动TaskRunner。在启动TaskRunner后,对于Map任务,会启动MapTaskRunner;对于Reduce任务则启动ReduceTaskRunner。

之后,TaskRunner又会启动新的Java虚拟机来运行每个任务(见图6-1的步骤⑩)。以Map任务为例,任务执行的简单流程是:

1)配置任务执行参数(获取Java程序的执行环境和配置参数等);

2)在Child临时文件表中添加Map任务信息(运行Map和Reduce任务的主进程是Child类);

3)配置log文件夹,然后配置Map任务的通信和输出参数;

4)读取input split,生成RecordReader读取数据;

5)为Map任务生成MapRunnable,依次从RecordReader中接收数据,并调用Mapper的Map函数进行处理;

6)最后将Map函数的输出调用collect收集到MapOutputBuffer中(见图6-1的步骤11)。