MapReduce作业提交与初始化过程
新版API通过job.waitForCompletion(true)提交作业,旧版API通过JobClient.runJob(conf)提交作业,但是两者最后都调用了JobClient类的submitJobInternal()方法,所以MapReduce作业提交就从submitJobInternal()方法开始讲解。
public RunningJob submitJobInternal(final JobConf job){
...... //获取作业ID JobID jobId = jobSubmitClient.getNewJobId(); ...... //创建HDFS目录,并通过DistributeCache上传作业文件 copyAndConfigureFiles(jobCopy, submitJobDir); ...... //通过InputFormat获取splites文件 int maps = writeSplits(context, submitJobDir); ...... //把客户端的配置属性写入XML文件中 jobCopy.writeXml(out); ...... //提交作业 status = jobSubmitClient.submitJob(jobId, submitJobDir.toString(), jobCopy.getCredentials());
...... }
submitJobInternal()方法中调用copyAndConfigureFiles()方法进行两个重要的准备工作:在HDFS下创建目录,然后把作业相关的文件分发到各台机器中。
jobSubmitClient.submitJob()这行代码通过JobClient和JobTracker的通信协议JobSubmissionProtocol调用JobTracker类下的submitJob()方法提交作业。
submitJob()方法中 status = addJob(jobId, job) 这样代码负责加载作业。addJob(jobId, job) 代码如下
private synchronized JobStatus addJob(JobID jobId, JobInProgress job) throws IOException { ......synchronized (jobs) { synchronized (taskScheduler) { jobs.put(job.getProfile().getJobID(), job); for (JobInProgressListener listener : jobInProgressListeners) { listener.jobAdded(job); //通知每个已经注册的JobInProgressListerner } } } ...... }
JobTracker采用了观察者设计模式,将提交作业作业这一件事告诉TaskScheduler。
在JobTracker的main方法中主要代码如下
public static void main(String argv[]) throws IOException, InterruptedException { ......
//初始化JobTracker参数,默认执行类为JobQueueTaskScheduler JobTracker tracker = startTracker(new JobConf());
//启动各种后台服务 tracker.offerService();
...... }
其中在offerService()方法中调用了JobQueueTaskScheduler类的start方法,如下
public synchronized void start() throws IOException { super.start();
//添加对jobQueueJobInProgressListener事件的监听 taskTrackerManager.addJobInProgressListener(jobQueueJobInProgressListener);
eagerTaskInitializationListener.setTaskTrackerManager(taskTrackerManager); eagerTaskInitializationListener.start();
//添加对eagerTaskInitializationListener事件的监听 taskTrackerManager.addJobInProgressListener(eagerTaskInitializationListener);
}
EagerTaskInitializationListener用于作业初始化,JobQueueJobInProgressListener用于作业排序。
offerService()方法会启动JobTracker内部几个比较重要的后台服务线程,代码如下
public void offerService() throws InterruptedException, IOException { ......
//主要用于发现和清理死掉的TaskTracker this.expireTrackersThread = new Thread(this.expireTrackers, "expireTrackers"); this.expireTrackersThread.start();
//主要用于长时间驻留在内存中的已经运行完成的作业信息 this.retireJobsThread = new Thread(this.retireJobs, "retireJobs"); this.retireJobsThread.start();
//主要用于发现已经被分配给某个TaskTracker但一直没有汇报信息的任务 expireLaunchingTaskThread.start();
//将已经运行完成的作业信息保存到HDFS上,并提供一套存取这些信息的API if (completedJobStatusStore.isActive()) { completedJobsStoreThread = new Thread(completedJobStatusStore, "completedjobsStore-housekeeper"); completedJobsStoreThread.start(); }
...... }


浙公网安备 33010602011771号