Hadoop作业提交与执行分析王挺Word文档下载推荐.docx

上传人:b****6 文档编号:18805697 上传时间:2023-01-01 格式:DOCX 页数:17 大小:161.59KB
下载 相关 举报
Hadoop作业提交与执行分析王挺Word文档下载推荐.docx_第1页
第1页 / 共17页
Hadoop作业提交与执行分析王挺Word文档下载推荐.docx_第2页
第2页 / 共17页
Hadoop作业提交与执行分析王挺Word文档下载推荐.docx_第3页
第3页 / 共17页
Hadoop作业提交与执行分析王挺Word文档下载推荐.docx_第4页
第4页 / 共17页
Hadoop作业提交与执行分析王挺Word文档下载推荐.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

Hadoop作业提交与执行分析王挺Word文档下载推荐.docx

《Hadoop作业提交与执行分析王挺Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Hadoop作业提交与执行分析王挺Word文档下载推荐.docx(17页珍藏版)》请在冰豆网上搜索。

Hadoop作业提交与执行分析王挺Word文档下载推荐.docx

//是否载入默认资源

privatestaticfinalWeakHashMap<

Configuration,Object>

REGISTRY=newWeakHashMap<

//

privatePropertiesproperties;

//个人程序所需要的所有配置会以Properties的形式存储

privatePropertiesoverlay;

/*它也是一个Properties变量。

它对应于finalResources列表,也就是解析finalResources列表中设置的配置文件,配置项设置到overlay中。

这里,overlay比较关键的一点就是,如果overlay不为空属性配置,在创建一个Configuration实例的时候会检查overlay,不空就将其中的配置项加入到properties中.*/

privateClassLoaderclassLoader;

//类加载器

在这里所有客户端程序中配置的类的信息和其他运行信息,都会保存在这个类里。

2.2 

JobClient.runJob()开始运行job并分解输入数据集

一个MapReduce的Job会通过JobClient类根据用户在JobConf类中定义的InputFormat实现类(通过getInputFormat()调用getClass()来得到)来将输入的数据集分解成一批小的数据集,每一个小数据集会对应创建一个MapTask来处理。

EagerTaskInitializationListener将调用JobInProcess.initTask根据InputSplit来创建map和reducetask,同时创建assistanttask,比如clean-uptask.

注:

InputFormat接口默认被FileInputFormat类实现,TextInputFormat类继承自FileInputFormat类。

FileInputFormat类里定义了一系列分解数据集的操作。

JobClient会使用缺省的TextInputFormat类调用TextInputFormat.getSplits()方法生成小数据集(通过InputFormat接口调用此方法),如果判断数据文件是isSplitable()的话,会将大的文件分解成小的FileSplit,当然只是记录文件在HDFS里的路径及偏移量和Split大小。

这些信息会统一打包到jobFile的jar中并存储在HDFS中,再将jobFile路径提交给JobTracker去调度和执行。

打包:

用户使用eclipse或者ant命令进行打包。

传输:

JobClient会使用copyRemoteFiles()方法拷贝文件到HDFS。

privatePathcopyRemoteFiles(FileSystemjtFs,PathparentDir,PathoriginalPath,JobConfjob,shortreplication)throwsIOException{

FileSystemremoteFs=null;

remoteFs=originalPath.getFileSystem(job);

if(compareFs(remoteFs,jtFs)){

returnoriginalPath;

}

PathnewPath=newPath(parentDir,originalPath.getName());

FileUtil.copy(remoteFs,originalPath,jtFs,newPath,false,job);

jtFs.setReplication(newPath,replication);

returnnewPath;

}

提交:

JobTracker实际获得的是Job对应的url.JobClient中,首先由Path实例化了一个submitJarFile,它包含了Jar文件的路径信息,然后调用configureCommandLineOptions()方法,此方法中使用了job.setJar()方法获得了一个路径的字符串形式。

2.3 

JobClient.submitJob()提交job到JobTracker

jobFile的提交过程是通过RPC模块来实现的。

大致过程是,JobClient类中通过RPC实现的Proxy接口(提前创建好了RPC代理)调用JobTracker的submitJob()方法,而JobTracker必须实现JobSubmissionProtocol接口。

createRPCproxy返回了一个实现JobSubmissionProtocol接口的对象叫做jobSubmitClient,JobClient通过此对象调用submitJob方法(submitJob又调用了submitJobInternal方法)来提交job.

submitJobInternal方法利用RPC调用JobTracker.submitJob(),submitJob方法调用addjob(),把job添加到JobInProgress中。

privatesynchronizedJobStatusaddJob(JobIDjobId,JobInProgressjob){

totalSubmissions++;

synchronized(jobs){

synchronized(taskScheduler){

jobs.put(job.getProfile().getJobID(),job);

for(JobInProgressListenerlistener:

jobInProgressListeners){

try{

listener.jobAdded(job);

}catch(IOExceptionioe){

LOG.warn("

Failedtoaddandsoskippingthejob:

"

+job.getJobID()+"

.Exception:

+ioe);

myInstrumentation.submitJob(job.getJobConf(),jobId);

returnjob.getStatus();

JobTracker则根据获得的jobFile路径创建与job有关的一系列对象(即JobInProgress和TaskInProgress等)来调度并执行job。

JobTracker创建job成功后会给JobClient传回一个JobStatus对象用于记录job的状态信息,如执行时间、Map和Reduce任务完成的比例等。

JobClient会根据这个JobStatus对象创建一个NetworkedJob的RunningJob对象,用于定时从JobTracker获得执行过程的统计数据来监控并打印到用户的控制台。

submitJob内部通过JobSubmitter的SubmitJobInternal进行实质性的提交,即提交三个文件,job.jar,job.split,job.xml这三个文件位置由mapreduce系统路径mapred.system.dir属性决定,写完这三个文件之后,此方法使用RPC调用master节点的JobTracker.submitJob(job)方法。

3Job执行过程

job统一由JobTracker来调度的,具体的Task分发给各个TaskTracker节点来执行。

3.1 

JobTracker初始化Job和Task队列过程

启动JobTracker后它会初始化若干个服务以及若干个内部线程用来维护job的执行过程和结果。

首先,JobTracker会启动一个interTrackerServer,端口配置在Configuration中的"

mapred.job.tracker"

参数,缺省是绑定8012端口。

它有两个用途,一是用于接收和处理TaskTracker的heartbeat等请求,即必须实现InterTrackerProtocol接口及协议。

二是用于接收和处理JobClient的请求,如submitJob,killJob等,即必须实现JobSubmissionProtocol接口及协议。

其次,它会启动一个infoServer线程,运行StatusHttpServer,缺省监听50030端口。

是一个web服务,用于给用户提供web界面查询job执行状况的服务。

JobTracker还会启动多个线程,ExpireLaunchingTasks线程用于停止那些未在超时时间内报告进度的Tasks。

ExpireTrackers线程用于停止那些可能已经当掉的TaskTracker,即长时间未报告的TaskTracker将不会再分配新的Task。

RetireJobs线程用于清除那些已经完成很长时间还存在队列里的jobs。

JobInitThread线程用于初始化job,这在前面章节已经介绍。

TaskCommitQueue线程用于调度Task的那些所有与FileSystem操作相关的处理,并记录Task的状态等信息。

3.1.1 

JobTracker.submitJob()收到请求

当JobTracker接收到新的job请求(即submitJob()函数被调用)后,会创建一个JobInProgress对象并通过它来管理和调度任务。

JobInProgressjob=newJobInProgress(jobId,this,this.conf);

JobInProgress在创建的时候会初始化一系列与任务有关的参数,如jobjar的位置(会把它从HDFS复制本地的文件系统中的临时目录里),Map和Reduce的数据,job的优先级别,以及记录统计报告的对象等。

publicJobInProgress(JobIDjobid,JobTrackerjobtracker,

JobConfdefault_conf,intrCount)throwsIOException{

this.restartCount=rCount;

this.jobId=jobid;

Stringurl="

http:

//"

+jobtracker.getJobTrackerMachine()+"

:

"

+jobtracker.getInfoPort()+"

/jobdetails.jsp?

jobid="

+jobid;

this.jobtracker=jobtracker;

this.status=newJobStatus(jobid,0.0f,0.0f,JobStatus.PREP);

this.startTime=System.currentTimeMillis();

status.setStartTime(startTime);

this.localFs=FileSystem.getLocal(default_conf);

JobConfdefault_job_conf=newJobConf(default_conf);

this.localJobFile=default_job_conf.getLocalPath(JobTracker.SUBDIR+"

/"

+jobid+"

.xml"

);

this.localJarFile=default_job_conf.getLocalPath(JobTracker.SUBDIR+"

+jobid+"

.jar"

PathjobDir=jobtracker.getSystemDirectoryForJob(jobId);

FileSystemfs=jobDir.getFileSystem(default_conf);

jobFile=newPath(jobDir,"

job.xml"

fs.copyToLocalFile(jobFile,localJobFile);

conf=newJobConf(localJobFile);

this.priority=conf.getJobPriority();

this.status.setJobPriority(this.priority);

this.profile=newJobProfile(conf.getUser(),jobid,jobFile.toString(),url,conf.getJobName(),conf.getQueueName());

StringjarFile=conf.getJar();

if(jarFile!

=null){

fs.copyToLocalFile(newPath(jarFile),localJarFile);

conf.setJar(localJarFile.toString());

this.numMapTasks=conf.getNumMapTasks();

this.numReduceTasks=conf.getNumReduceTasks();

this.taskCompletionEvents=newArrayList<

TaskCompletionEvent>

(numMapTasks+numReduceTasks+10);

this.mapFailuresPercent=conf.getMaxMapTaskFailuresPercent();

this.reduceFailuresPercent=conf.getMaxReduceTaskFailuresPercent();

MetricsContextmetricsContext=MetricsUtil.getContext("

mapred"

this.jobMetrics=MetricsUtil.createRecord(metricsContext,"

job"

this.jobMetrics.setTag("

user"

conf.getUser());

sessionId"

conf.getSessionId());

jobName"

conf.getJobName());

jobId"

jobid.toString());

hasSpeculativeMaps=conf.getMapSpeculativeExecution();

hasSpeculativeReduces=conf.getReduceSpeculativeExecution();

this.maxLevel=jobtracker.getNumTaskCacheLevels();

this.anyCacheLevel=this.maxLevel+1;

this.nonLocalMaps=newLinkedList<

TaskInProgress>

this.nonLocalRunningMaps=newLinkedHashSet<

this.runningMapCache=newIdentityHashMap<

Node,Set<

>

this.nonRunningReduces=newLinkedList<

this.runningReduces=newLinkedHashSet<

this.resourceEstimator=newResourceEstimator(this);

3.1.2 

JobTracker.setJobPriority()设置优先级

JobInProgress创建后,首先将它加入到jobs队列里,分别用一个map成员变量jobs用来管理所有jobs对象,一个string变量priority用来维护jobs的执行优先级别。

之后JobTracker会调用resortPriority()函数,将jobs先按优先级别排序,再按提交时间排序,这样保证最高优先并且先提交的job会先执行。

publicsynchronizedvoidsetJobPriority(JobIDjobid,Stringpriority)throwsIOException{

JobInProgressjob=jobs.get(jobid);

if(null==job){

LOG.info("

setJobPriority():

JobId"

+jobid.toString()

+"

isnotavalidjob"

return;

checkAccess(job,QueueManager.QueueOperation.ADMINISTER_JOBS);

JobPrioritynewPriority=JobPriority.valueOf(priority);

setJobPriority(jobid,newPriority);

3.1.3 

JobTracker.InitJob通知初始化线程

然后JobTracker会把此job加入到一个管理需要初始化的队列里,即一个list成员变量jobInitQueue里。

通过此成员变量调用notifyAll()函数,会唤起一个用于初始化job的线程InitJob来处理。

InitJob收到信号后即取出最靠前的job,即优先级别最高的job,调用JobInProgress的initTasks()函数执行真正的初始化工作。

publicvoidinitJob(JobInProgressjob){

Initonnulljobisnotvalid"

}

JobStatusprevStatus=(JobStatus)job.getStatus().clone();

Initializing"

+job.getJobID());

job.initTasks();

//Informthelistenersifthejobstatehaschanged

//Note:

thatthejobwillbeinPREPstate.

JobStatusnewStatus=(JobStatus)job.getStatus().clone();

if(prevStatus.getRunState()!

=newStatus.getRunState()){

JobStatusChangeEventevent=

newJobStatusChangeEvent(job,EventType.RUN_STATE_CHANGED,prevStatus,

newStatus);

synchronized(JobTracker.this){

updateJobInProgressListeners(event);

}catch(KillInterruptedExceptionkie){

//Ifjobwaskilledduringinitialization,jobstatewillbeKILLED

LOG.error("

Jobinitializationinterrupted:

\n"

+

StringUtils.stringifyException(kie));

killJob(job);

}catch(Throwablet){

//Ifthejobinitializationisfailed,jobstatewillbeFAILED

Jobinitializationfailed:

StringUtils.stringifyException(t));

failJob(job);

3.1.4 

JobInProgress.initTasks()初始化TaskInProgress

Task的初始化过程稍复杂些,首先步骤JobInProgress会创建Map的监控对象。

在initTasks()函数里通过调用JobClient的readSplitFile()获得已分解的输入数据的RawSplit列表,然后根据这个列表创建对应数目的Map执行管理对象TaskInProgress。

在这个过程中,还会记录该RawSplit块对应的所有在HDFS里的blocks所在的DataNode节点的host,这个会在RawSplit创建时通过FileSplit的getLocations()函数获取,该函数会调用DistributedFileSystem的getFileCacheHints()获得(具体在HDFS模块中)。

当然如果是存储在本地文件系统中,即使用LocalFileSystem时当然只有一个location即“localhost”了。

其次JobInProgress会创建Reduce的监控对象,这个比较简单,根据JobConf里指定的Reduce

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 高考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1