Job 提交&初始化

来源:互联网 发布:华夏银行贵金属软件 编辑:程序博客网 时间:2024/05/16 01:51

简述步骤:

1、通过Shell命令提交job

2、JobClient将Job运行所需要的文件upload到JobTracker文件系统(如hdfs)的某个目录下

3、JobClient通过RPC向JobClient提交作业

4、JobClient告知TaskScheduler,由TaskScheduler对作业进行初始化

 

具体实现(以WordCount为例),详见源码WordCount.java:

1、$HADOOP_HOME/bin/hadoop脚本中根据“jar”命令将job传给RunJar类处理。

2、RunJar类的main函数解压jar包,获取jar包中的mainClass,并调用其中的main函数执行,如:

<span style="font-size:14px;">public static void main(String[] args) throws Exception {    int res = ToolRunner.run(new Configuration(), new WordCount(), args);    System.exit(res);  }</span>

3、调用wordCount中的run()函数,构建JobConf,并在其中调用 JobClient.runJob(conf)

4、new JobClient,其中通过{mapred.job.tracker}参数确定将作业提交到local还是hdfs,如果是hdfs,则建立于job Tracker的rpc链接

5、submitJob()=>submitJobInternal():

      Path jobStagingArea = JobSubmissionFiles.getStagingDir(JobClient.this, jobCopy);//通过RPC向JobTracker获取配置项{"mapreduce.jobtracker.staging.root.dir“},

     JobID jobId = jobSubmitClient.getNewJobId();//向JobTracker申请jobId

     Path submitJobDir = new Path(jobStagingArea, jobId.toString());//构造上传的文件目录submitJobDir

     调用copyAndConfigureFiles()将存放上传文件的文件系统与jobclient所在的文件系统对比,不一致则需要上传,并设置副本数(默认10)。

6、获取文件系统:FileSystem fs = submitJobDir.getFileSystem(job),最终调用createFileSystem():

<span style="font-size:14px;">private static FileSystem createFileSystem(URI uri, Configuration conf      ) throws IOException {    Class<?> clazz = conf.getClass("fs." + uri.getScheme() + ".impl", null);    LOG.debug("Creating filesystem for " + uri);    if (clazz == null) {      throw new IOException("No FileSystem for scheme: " + uri.getScheme());    }    FileSystem fs = (FileSystem)ReflectionUtils.newInstance(clazz, conf);    fs.initialize(uri, conf);    return fs;  }</span>

如果jobSubmitClient是JobTracker的实例,那Scheme就是hdfs。如果是LocalJobRunner的实例,那就是file。从core-default.xml你可以找到如下的信息:

<property>
<name>fs.file.impl</name>
<value>org.apache.hadoop.fs.LocalFileSystem</value>
<description>The FileSystem for file: uris.</description>
</property>

 

<property>
<name>fs.hdfs.impl</name>
<value>org.apache.hadoop.hdfs.DistributedFileSystem</value>
<description>The FileSystem for hdfs: uris.</description>
</property>

可以看到,最终通过反射技术,确定用到哪一个类进行实例化。

7、拷贝文件到local或者hdfs,继而调用writeSplit是(),writeXml()上传

8、调用RPC接口submitJob将作业提交到JobTracker端。

 

submitJob():

(1)如果是新的Job,则new一个JobInfo,用于记录该job的信息,包括jobId,username,jobsubmitDir等。

(2)根据配置文件"mapred.system.dir",创建该目录及该目录下的文件,用于存放jobInfo的信息。

(3)创建一个JobInProgress,该对象维护了作业运行时信息。

注:在该构造函数中,会从配置中获取"mapred.job.queue.name"的值queue,并记录在JobProfile对象中。而在JobTracker构造函数中,会根据配置项"mapred.queue.names",构造所有的队列映射queues

(4)判断本次操作的用户是否具有该queue的job提交权限

(5)检查作业配置的内存使用量是否合理

(6)通过调用AddJob将作业新增到两个JobInProgressListener中,然后在这两个Listen中就会触发相应的行为:

          注:JobTracker启动时会根据配置项将用户配置的任务调度器构造好,并在start()后进行初始化,此时,调度器会向JobTracker注册两个JobInProgressListener对象以监听作业的新增,删除等操作。分别用于作业初始化和作业排序。

 

初始化监听器EagerTaskInitializationListener:

AddJob后,初始化监听器中将新增一个job到jobInitQueue中;

EagerTaskInitializationListener在调用start之后,将运行JobInitManager线程函数。内部从jobInitQueue从取出第一个,调用JobTracker的initJob进行初始化。

实际通过job.initTasks();真正实现初始化的工作,内部获取TaskSplitMetaInfo[ ],为每一个split创建一个map。又创建reduce [ ],又为每一个job的map和reduce分别创建一个cleanup任务,为每一个job的map和reduce分别创建一个setup任务。

初始化后,将jobStatus更新到所有的Listen中进行通知。至此,作业初始化工作结束。

 

 

 

0 0
原创粉丝点击