Hadoop MapReduce 是大数据计算生态的基础。深入理解其作业提交的源码流程,不仅有助于故障排查和性能优化,也是大数据工程师进阶和面试的必备技能。本文将以源码为主线,结合流程图、设计模式、参数说明和调试技巧,全面剖析 MapReduce 客户端提交作业的每个核心环节,助你掌握底层原理与实战方法。
hadoop jar myjob.jar com.example.MyJob -D mapreduce.job.queuename=default
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "MyJob");
job.setJarByClass(MyJob.class);
// ...配置Mapper、Reducer等
job.waitForCompletion(true);
客户端
|
|--> Job.waitForCompletion()/submit()
|
|--> JobSubmitter.submitJobInternal()
|
|--> 检查输出目录
|--> 上传资源到HDFS
|--> 写 job.xml
|--> submitClient.submitJob()
|
|--> YARNRunner.submitJob()
|
|--> 构建 ApplicationSubmissionContext
|--> ApplicationClientProtocol.submitApplication()
|
|--> ResourceManager 注册 Application
Job.getInstance()
, setJarByClass()
, setMapperClass()
, setReducerClass()
, setOutputPath()
mapreduce.job.name
:作业名称mapreduce.job.queuename
:队列名称mapreduce.job.jar
:作业jar包路径mapreduce.input.fileinputformat.inputdir
:输入目录mapreduce.output.fileoutputformat.outputdir
:输出目录代码片段与注释:
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "myjob");
job.setJarByClass(MyJob.class); // 指定主类,方便YARN找jar
job.setMapperClass(MyMapper.class);
job.setReducerClass(MyReducer.class);
FileInputFormat.setInputPaths(job, new Path("/input"));
FileOutputFormat.setOutputPath(job, new Path("/output"));
口诀:
配置Job,指定类,输入输出,作业名
调试技巧:
conf.writeXml(System.out)
输出配置信息,排查参数问题。job.setJarByClass()
是否设置正确,否则YARN节点找不到主类。Job.submit()
代码片段与注释:
public void submit() throws IOException, InterruptedException, ClassNotFoundException {
ensureState(JobState.DEFINE); // 只能在DEFINE状态提交
JobSubmitter submitter = new JobSubmitter(getCluster(), getConfiguration());
status = ugi.doAs(new PrivilegedExceptionAction<JobStatus>() {
public JobStatus run() throws IOException, InterruptedException, ClassNotFoundException {
return submitter.submitJobInternal(Job.this, cluster);
}
});
state = JobState.RUNNING;
}
口诀:
检查状态,建Submitter,代理提交,状态变
调试技巧:
JobSubmitter.submitJobInternal(Job job, Cluster cluster)
代码片段与注释:
JobStatus submitJobInternal(Job job, Cluster cluster) throws ... {
checkSpecs(job); // 检查输出路径是否存在
Path jobStagingArea = JobSubmissionFiles.getStagingDir(cluster, conf); // 获取临时目录
JobID jobId = submitClient.getNewJobID(); // 获取新JobID
Path submitJobDir = new Path(jobStagingArea, jobId.toString());
copyAndConfigureFiles(job, submitJobDir); // 拷贝jar、依赖、配置到HDFS
submitClient.submitJob(jobId, submitJobDir.toString(), job.getCredentials()); // 提交给YARN
return submitClient.getJobStatus(jobId);
}
口诀:
查输出,建目录,拷文件,写配置,YARN提交
调试技巧:
/tmp/hadoop-yarn/staging
查看。YARNRunner.submitJob(JobID, String, Credentials)
代码片段与注释:
@Override
public JobStatus submitJob(JobID jobId, String jobSubmitDir, Credentials ts) throws IOException {
// 构建 ApplicationSubmissionContext,描述AM启动信息、资源等
SubmitApplicationRequest request = ...;
applicationClient.submitApplication(request); // 发送给ResourceManager
// 返回JobStatus
}
口诀:
建上下文,YARN请求,收作业状态
调试技巧:
yarn application -status
跟踪作业。yarn logs -applicationId
查看详细日志。配置Job,提Job,查输出,拷资源,写配置,YARN提交,建上下文,YARN请求,收状态!
参数名 | 作用 | 常见调试建议 |
---|---|---|
mapreduce.job.name | 作业名称 | 用于作业区分及日志检索 |
mapreduce.job.queuename | YARN队列名 | 队列无权限会失败,需检查 |
mapreduce.job.jar | 作业JAR包路径 | 没设置会导致YARN节点找不到类 |
mapreduce.input.fileinputformat.inputdir | 输入目录 | 目录不存在会报错 |
mapreduce.output.fileoutputformat.outputdir | 输出目录 | 已存在会失败,需预先清理 |
调试技巧总览:
rm -r /output
或换新目录yarn logs -applicationId
查看详细报错conf.writeXml(System.out)
输出配置信息阶段 | 设计模式 | 方法论 |
---|---|---|
Job配置 | 建造者模式 | 参数分层 |
Job.submit | 代理模式 | 权限隔离 |
作业准备上传 | 模板方法模式 | 资源封装 |
YARNRunner提交 | 适配器模式 | 分层解耦 |
整体架构 | 分层架构 | 责任分离 |
本文由大模型整理优化,专注大数据底层原理与源码剖析。欢迎收藏、转发和留言交流!