在Mapreduce v1中是使用JobClient来和JobTracker交互完成Job的提交,用户先创建一个Job,通过JobConf设置好参数,通过JobClient提交并监控Job的进展,在JobClient中有一个内部成员变量JobSubmissionProtocol,JobTracker实现了该接口,通过该协议客户端和JobTracker通信完成作业的提交
  public void init(JobConf conf) throws IOException {
String tracker = conf.get("mapred.job.tracker", "local");
tasklogtimeout = conf.getInt(
TASKLOG_PULL_TIMEOUT_KEY, DEFAULT_TASKLOG_TIMEOUT);
this.ugi = UserGroupInformation.getCurrentUser();
//如果mapred.job.tracker设置成local,则创建本地LocalJobRunner,否则创建RPC代理
if ("local".equals(tracker)) {
conf.setNumMapTasks(1);
this.jobSubmitClient = new LocalJobRunner(conf);
} else {
this.jobSubmitClient = createRPCProxy(JobTracker.getAddress(conf), conf);
}
}
按顺序调用: 
Job.waitForCompletion()
Job.submit()
jobClient.submitJobInternal()
jobSubmitClient.submitJob(jobId, submitJobDir.toString(), jobCopy.getCredentials()) 
完成作业提交
而YARN的作业提交procotol是ClientRMProtocol,
提交MRv2作业时,首先会生成集群信息类cluster,里面有一个frameworkLoader内部变量会从配置文件中加载ClientProtocolProvider的实现类,这里 分别是LocalClientProtocolProvider和 YarnClientProtocolProvider 。Cluster类在initialize中,会遍历frameworkLoader,由ClientProtocolProvider来生成具体的ClientProtocol ,比如在YarnClientProtocolProvider中就会判断JobConf中的 mapreduce.framework.name是否为 yarn,如果是的话则会生成YARNRunner
YarnClientProtocolProvider的create方法:
  @Override
public ClientProtocol create(Configuration conf) throws IOException {
if (MRConfig.YARN_FRAMEWORK_NAME.equals(conf.get(MRConfig.FRAMEWORK_NAME))) {
return new YARNRunner(conf);
}
return null;
}
ClientProtocol目前有两个实现 YARNRunner 和LocalJobRunner,LocalJobRunner(mapreduce.framework.name为local )主要是在本地执行mapreduce,可以方便对程序进行调试。YARNRunner是将作业提交到YARN上 。
YARNRunner初始化会和ResourceManager建立RPC链接(默认是8032端口
),真正和RM通信的协议是
ClientRMProtocol
,客户端和RM交互的所有操作都会通过YARNRunner的成员变量
rmClient(
ClientRMProtocol
)提交出去,比如killApplication, getNodeReports, getJobCounters等等
  public synchronized void start() {
YarnRPC rpc = YarnRPC.create(getConfig());
this.rmClient = (ClientRMProtocol) rpc.getProxy(
ClientRMProtocol.class, rmAddress, getConfig());
if (LOG.isDebugEnabled()) {
LOG.debug("Connecting to ResourceManager at " + rmAddress);
}
super.start();
}
Cluster类初始化完成后,就要生成Application了,先和RM通信申请一个Application(getNewApplication ),得到一个GetNewApplicationResponse,里面封装了ApplicationID,和RM能提供的最小、最大Resource Capacity
public interface GetNewApplicationResponse {
public abstract ApplicationId getApplicationId();
public Resource getMinimumResourceCapability();
public Resource getMaximumResourceCapability();
public void setMaximumResourceCapability(Resource capability);
}

Resource定义了一组集群计算资源,目前只把memory和cpu纳入进来,这边的cpu指virtual core,也就是一个物理core可以被认为抽象成多个virtual core,而非一对一对应关系

public abstract class Resource implements Comparable<Resource> {
public abstract int getMemory();
public abstract void setMemory(int memory);
public abstract int getVirtualCores();
public abstract void setVirtualCores(int vCores);
}

然后需要构造ApplicationSubmissionContext,其中包含了启动MR AM的信息, 比如提交的job在HDFS的staging目录路径(job.xml,  job.split, job.splitmetainfo, libjars, files, archives等 ),用户ugi信息,Secure Tokens。完成context构造后,调用resMgrDelegate.submitApplication(appContext)
YARNRunner的submitJob方法:
  @Override
public JobStatus submitJob(JobID jobId, String jobSubmitDir, Credentials ts)
throws IOException, InterruptedException {
// Construct necessary information to start the MR AM
ApplicationSubmissionContext appContext =
createApplicationSubmissionContext(conf, jobSubmitDir, ts); // Submit to ResourceManager
ApplicationId applicationId = resMgrDelegate.submitApplication(appContext); ApplicationReport appMaster = resMgrDelegate.getApplicationReport(applicationId);
String diagnostics = (appMaster == null ?
"application report is null" : appMaster.getDiagnostics());
if (appMaster == null || appMaster.getYarnApplicationState() == YarnApplicationState.FAILED
|| appMaster.getYarnApplicationState() == YarnApplicationState.KILLED) {
throw new IOException("Failed to run job : " +
diagnostics);
}
return clientCache.getClient(jobId).getJobStatus(jobId);
}

最后通过getJobStatus方法获得Job状态信息

    org.apache.hadoop.mapreduce.v2.api.records.JobId jobId =
TypeConverter.toYarn(oldJobID);
GetJobReportRequest request =
recordFactory.newRecordInstance(GetJobReportRequest.class);
request.setJobId(jobId);
JobReport report = ((GetJobReportResponse) invoke("getJobReport",
GetJobReportRequest.class, request)).getJobReport();

客户端MapReduce提交到YARN过程的更多相关文章

  1. 经典MapReduce作业和Yarn上MapReduce作业运行机制

    一.经典MapReduce的作业运行机制 如下图是经典MapReduce作业的工作原理: 1.1 经典MapReduce作业的实体 经典MapReduce作业运行过程包含的实体: 客户端,提交MapR ...

  2. spark-submit提交python脚本过程记录

    最近刚学习spark,用spark-submit命令提交一个python脚本,一开始老报错,所以打算好好整理一下用spark-submit命令提交python脚本的过程.先看一下spark-submi ...

  3. 【Hadoop代码笔记】Hadoop作业提交之客户端作业提交

    1.      概要描述仅仅描述向Hadoop提交作业的第一步,即调用Jobclient的submitJob方法,向Hadoop提交作业. 2.      详细描述Jobclient使用内置的JobS ...

  4. spark任务提交到yarn上命令总结

    spark任务提交到yarn上命令总结 1. 使用spark-submit提交任务 集群模式执行 SparkPi 任务,指定资源使用,指定eventLog目录 spark-submit --class ...

  5. rpc,客户端与NameNode通信的过程

    远程过程:java进程.即一个java进程调用另外一个java进程中对象的方法. 调用方称作客户端(client),被调用方称作服务端(server).rpc的通信在java中表现为客户端去调用服务端 ...

  6. Android BLE与终端通信(三)——客户端与服务端通信过程以及实现数据通信

    Android BLE与终端通信(三)--客户端与服务端通信过程以及实现数据通信 前面的终究只是小知识点,上不了台面,也只能算是起到一个科普的作用,而同步到实际的开发上去,今天就来延续前两篇实现蓝牙主 ...

  7. Migrating from MapReduce 1 (MRv1) to MapReduce 2 (MRv2, YARN)...

    This is a guide to migrating from Apache MapReduce 1 (MRv1) to the Next Generation MapReduce (MRv2 o ...

  8. Oracle11g R2客户端安装图文详解过程

    转: Oracle11g R2客户端安装图文详解过程 2018-06-17 13:30:26 大话JAVA的那些事 阅读数 4129更多 分类专栏: Oracle   版权声明:本文为博主原创文章,遵 ...

  9. 3.MapReduce原理和Yarn

    1.MapReduce原理 2.MapReduce执行时间 3.MapReduce开发 4.Yarn

随机推荐

  1. the c programming language 2-3

    #include<stdio.h> #define MAXLINELEN 1000 int power(int base,int n) { ; ; ;i<n;i++) answer= ...

  2. 一个在线的C++帮助文档网站 转载

    http://www.cplusplus.com/          //C++参考 http://www.cppreference.com/wiki/start       //C++参考 http ...

  3. npm 好用工具 for 前端

    1. caniuse npm install -g caniuse-cmd

  4. eclipse下使用Genymotion调试Android程序出现的问题

    一. The connection to adb is down, and a severe error has occured. You must restart adb and Eclipse. ...

  5. jquery前端性能优化(持续添加。。。)

    1.选择器的使用 (1)$('#id')   使用id来定位dom元素是性能最高的方法.jQuery底层将直接调用本地方法document.getElementById().如果id直接可以找到所要对 ...

  6. jquery 中 form的使用

    纠结了一下 form 表单的提交响应事件,因为在表单中,form标签会让浏览器自动提交,而我一直写的是 $(".btn").click(function()) 提交按钮的响应事件, ...

  7. 通过try、except和else的使用来使Python程序更加“强壮”

    在执行的程序中,难免会碰到因为一些原因如输入输出导致致命性错误产生的情况(如因为输入的文件名错误而导致无法运行相关的代码.).此时你不希望程序直接挂掉,而是通过显示一些信息,使其平稳的结束.此时,就可 ...

  8. User Commands

    archive Creates a hadoop archive[v.存档; n.档案文件; 档案室; ]. More information can be found at Hadoop Archi ...

  9. 2的N次方

    /**编程精确计算2的N次方.(N是介于100和1000之间的整数)*//*问题代码:#include<stdio.h>#include<math.h>int main(){ ...

  10. 《C和指针》章节后编程练习解答参考——第8章

    8.1 #include <stdio.h> int main (void) { int a, b, c, d; // 不使用嵌套花括号初始化 unsigned ][][][] = { , ...