mapreduce源码分析之JobTracker
来源:互联网 发布:网络中央电视台 编辑:程序博客网 时间:2024/05/16 19:23
以下是我研究mapreduce源码的几个步骤,其中没有涉及太多的细节问题,主要就是先将思路理清,为以后继续深入研究做点笔记,主要涉及到map和reduce任务的执行步骤,首先从JobTracler的启动开始,之后到TaskTracker的启动,TaskTracker通过心跳机制再次回到JobTracker,然后再看JobTracker是怎样回复心跳的,然后又会有TaskTracker接受HeartBeatResponse的一系列动作,最后很自然就看到了map和reduce任务是怎样执行的,最后回到mapreduce包中,mapreduce包中会有一些抽象类以及具体实现的类(在mapreduce.lib中),大概就是这样一个思路,能理清这样的思路要感谢豆丁网的一位网友的博文(我再次找的时候已经找不到了)以及“觉先”的博文!
一.JobTracker的启动:
JobTracker里面里面有一个main方法,调试时用的,真正应用中在namenode中会启动该方法,main方法里面调用两个方法,分别是StartTracker和OfferSrervice,第一个方法是调用JobTracker的构造函数生成它的对象,并进行一些初始化,包括启动RPCSERVER,内置的jetty服务器,是否重启JobTracker等,第二个方法调用了TaskScheduler的start方法,TaskScheduler是一个抽象类,由JobQueueTaskScheduler具体来实现它,所以真正调用的是JobQueueTaskScheduler的start方法,下面来分析这个start方法来带的一系列效应:
该方法主要是注册了两个很重要的监听器,JobQueueJobInProgressListener和eagerTaskIntinilionListener,它们都是extends自JobInProgressListener,代码如下:
----------------------------------------------------------------------------------------------------------------------
@Override
publicsynchronizedvoidstart()throwsIOException{
super.start();
taskTrackerManager.addJobInProgressListener(jobQueueJobInProgressListener);
eagerTaskInitializationListener.setTaskTrackerManager(taskTrackerManager);
eagerTaskInitializationListener.start();
taskTrackerManager.addJobInProgressListener(
eagerTaskInitializationListener);
}
----------------------------------------------------------------------------------------------------------------------
第一个监听器是以FIFO的方式来维护一个JobInProgress队列的,并且监听各个JobInProgress实例的生命周期(之后再好好研究。。。),第二个eagerTaskIntinilionListener是EagerTaskIntinilionListener的一个实例,jobInitQueue主要是在这个类里面生成,它是一个arraylist,所以EagerTaskIntinilionListener是用来监听jobInitQueue,一旦有新的job提交,也就是有JobInProgress的实例加入,就会触发JobInProgress实例的initTask方法,对job进行初始化。这个initTask方法比较复杂,我先按照一条轴线来分析,其他的代码之后再研究,代码如下:
----------------------------------------------------------------------------------------------------------------------
publicsynchronizedvoidinitTasks()
throwsIOException,KillInterruptedException{
。。。
。。。
。。。
//readinputsplitsandcreateamapperasplit
//从HDFS中读取job.spilt文件从而生成inputspilts
StringjobFile=profile.getJobFile();
PathsysDir=newPath(this.jobtracker.getSystemDir());
FileSystemfs=sysDir.getFileSystem(conf);
DataInputStream splitFile =
fs.open(newPath(conf.get("mapred.job.split.file")));
JobClient.RawSplit[] splits;
try{
splits =JobClient.readSplitFile(splitFile);
}finally{
splitFile.close();
}
//map的个数就是split的个数
numMapTasks=splits.length;
//ifthenumberofsplitsislargerthanaconfiguredvalue
//thenfailthejob.
intmaxTasks=jobtracker.getMaxTasksPerJob();
if(maxTasks>0&&numMapTasks+numReduceTasks>maxTasks){
thrownewIOException(
"Thenumberoftasksforthisjob"+
(numMapTasks+numReduceTasks)+
"exceedstheconfiguredlimit"+maxTasks);
}
jobtracker.getInstrumentation().addWaiting(
getJobID(),numMapTasks+numReduceTasks);
//为每一个maptask生成一个TaskInProgress来处理
maps=newTaskInProgress[numMapTasks];
for(inti=0;i<numMapTasks;++i){
inputLength+=splits[i].getDataLength();
maps[i]=newTaskInProgress(jobId,jobFile,
splits[i],
jobtracker,conf,this,i);
}
LOG.info("Inputsizeforjob"+jobId+"="+inputLength
+".Numberofsplits="+splits.length);
if(numMapTasks>0){
nonRunningMapCache=createCache(splits,maxLevel);
}
}
----------------------------------------------------------------------------------------------------------------------
对于maptask,将其放入nonRunningMapCache里面,他是一个Map<Node,List<TaskInProgress>>,对于maptask来讲,他会被分配到inputsplit所在的Node上,Node在此表示DataNode或者机架或者数据中心,nonRunningMapCache将在Jobtracker向TaskTracker分配maptask的时候用到。。。
----------------------------------------------------------------------------------------------------------------------
nonRunningMapCache=createCache(splits,maxLevel);
----------------------------------------------------------------------------------------------------------------------
然后再创建reducetask,放入nonRunningReduces里面,将在Jobtracker想TaskTracker分配reducetask的时候用到。。。
-----------------------------------------------------------------------------------------
this.reduces=newTaskInProgress[numReduceTasks];
for(inti=0;i<numReduceTasks;i++){
reduces[i]=newTaskInProgress(jobId,jobFile,
numMapTasks,i,
jobtracker,conf,this);
nonRunningReduces.add(reduces[i]);
}
-----------------------------------------------------------------------------------------
创建两个cleanuptask,用来清理map和reduce
-----------------------------------------------------------------------------------------
//create cleanup two cleanup tips, one map and one reduce.
cleanup=newTaskInProgress[2];
//cleanupmaptip.Thismapdoesn'tuseanysplits.Justassignanempty
//split.
JobClient.RawSplitemptySplit=newJobClient.RawSplit();
cleanup[0]=newTaskInProgress(jobId,jobFile,emptySplit,
jobtracker,conf,this,numMapTasks);
cleanup[0].setJobCleanupTask();
//cleanupreducetip.
cleanup[1]=newTaskInProgress(jobId,jobFile,numMapTasks,
numReduceTasks,jobtracker,conf,this);
cleanup[1].setJobCleanupTask();
-----------------------------------------------------------------------------------------
创建两个初始化task,一个初始化map,一个初始化reduce
-----------------------------------------------------------------------------------------
//create two setup tips, one map and one reduce.
setup=newTaskInProgress[2];
//setupmaptip.Thismapdoesn'tuseanysplit.Justassignanempty
//split.
setup[0]=newTaskInProgress(jobId,jobFile,emptySplit,
jobtracker,conf,this,numMapTasks+1);
setup[0].setJobSetupTask();
//setupreducetip.
setup[1]=newTaskInProgress(jobId,jobFile,numMapTasks,
numReduceTasks+1,jobtracker,conf,this);
setup[1].setJobSetupTask();
最后看到tasksInited.set(true)方法,说明初始化完成,其他方法之后再看。
----------------------------------------------------------------------------------------------------------------------
synchronized(jobInitKillStatus){
jobInitKillStatus.initDone=true;
if(jobInitKillStatus.killed){
thrownewKillInterruptedException("Job"+jobId+"killedininit");
}
}
tasksInited.set(true);
JobHistory.JobInfo.logInited(profile.getJobID(),this.launchTime,
numMapTasks,numReduceTasks);
- mapreduce源码分析之JobTracker
- Hadoop之JobTracker源码分析
- MapReduce源码分析之Eclipse中的代码如何提交给JobTracker
- Hadoop源码之JobTracker
- Hadoop源码之JobTracker
- mapreduce中jobtracker进程的分析
- MapReduce源码解读系列之——作业如何提交到JobTracker
- MapReduce源码分析之InputFormat
- MapReduce源码分析之LocatedFileStatusFetcher
- MapReduce源码分析之JobSplitWriter
- MapReduce源码分析之InputSplit分析
- MapReduce源码分析之架构分析1
- MapReduce源码分析之MapTask分析
- MapReduce源码分析之MapTask分析(二)
- MapReduce源码分析之MapTask分析(二)
- MapReduce源码分析之InputSplit分析
- MapReduce源码分析之InputSplit分析
- 图说MapReduce源码--JobTracker.getSetupAndCleanupTasks 任务选择顺序
- 艺术节
- object-c
- java图片大小处理(缩放&切割&类型转换&色彩转换)
- poj 3254---Corn Fields
- jQuery制作可以编辑的表格
- mapreduce源码分析之JobTracker
- fedora9下使用QT连接数据库(QSqlDatabase: QODBC driver not loaded)
- 内存。二重指针,指针的高级使用
- 计算机图形学系列相关文章索引(持续更新)
- VC++ Progress Control
- 自己写的一个启动JBoss服务器的bat批处理
- AndroidNote010.Android访问webservice(上)服务器端
- POI框架导出EXCEL的简单列子(跨行跨列)合并单元格
- swing jtable常用