MapReduce调度与执行原理系列文章
转自:http://blog.csdn.net/jaytalent?viewmode=contents
MapReduce调度与执行原理系列文章
前言:本文旨在理清在Hadoop中一个MapReduce作业(Job)在提交到框架后的整个生命周期过程,权作总结和日后参考,如有问题,请不吝赐教。本文不涉及Hadoop的架构设计,如有兴趣请参考相关书籍和文献。在梳理过程中,我对一些感兴趣的源码也会逐行研究学习,以期强化基础。
作者:Jaytalent
开始日期:2013年9月9日参考资料:【1】《Hadoop技术内幕--深入解析MapReduce架构设计与实现原理》董西成【2】Hadoop 1.0.0 源码
- Job job = new Job(conf, "word count");
- job.setJarByClass(WordCount.class);
- job.setMapperClass(TokenizerMapper.class);
- job.setCombinerClass(IntSumReducer.class);
- job.setReducerClass(IntSumReducer.class);
- job.setOutputKeyClass(Text.class);
- job.setOutputValueClass(IntWritable.class);
- FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
- FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
- System.exit(job.waitForCompletion(true) ? 0 : 1);
- JobID jobId = jobSubmitClient.getNewJobId();
作业ID时从JobTracker获取的,这是一次RPC调用,方法为getNewJobId,定义在JobSubmissionProtocol接口。
- private JobSubmissionProtocol jobSubmitClient;
- /**
- * Allocate a name for the job.
- * @return a unique job name for submitting jobs.
- * @throws IOException
- */
- public JobID getNewJobId() throws IOException;
用户使用该协议通过JobTracker提交作业,查看作业状态等。
- copyAndConfigureFiles(jobCopy, submitJobDir);
在配置了提交副本数(mapred.submit.replication,默认为10)等信息后,主要代码分析如下(为了清晰起见,省略了一些日志和异常处理):
- // Retrieve command line arguments placed into the JobConf
- // by GenericOptionsParser.
- String files = job.get("tmpfiles");
- String libjars = job.get("tmpjars");
- String archives = job.get("tmparchives");
首先,从配置中获取不同类型文件的名称和路径,这些配置在作业提交时从命令行(Hadoop Shell)指定。files表示作业依赖的普通文件,比如文本文件;libjars表示应用程序依赖的第三方jar包;archives表示应用程序使用的多个文件打包而成的压缩文件。
- // Create a number of filenames in the JobTracker's fs namespace
- FileSystem fs = submitJobDir.getFileSystem(job);
- submitJobDir = fs.makeQualified(submitJobDir);
- FsPermission mapredSysPerms = new FsPermission(JobSubmissionFiles.JOB_DIR_PERMISSION);
- FileSystem.mkdirs(fs, submitJobDir, mapredSysPerms);
- Path filesDir = JobSubmissionFiles.getJobDistCacheFiles(submitJobDir);
- Path archivesDir = JobSubmissionFiles.getJobDistCacheArchives(submitJobDir);
- Path libjarsDir = JobSubmissionFiles.getJobDistCacheLibjars(submitJobDir);
接下来,在JobTracker的文件系统(通常为HDFS)的命名空间创建一系列文件路径名,其中包括前述三种文件类型。
有了路径名后,在HDFS上创建路径并将这些文件拷贝到对应的目录中,代码如下:
- // add all the command line files/ jars and archive
- // first copy them to jobtrackers filesystem
- if (files != null) {
- FileSystem.mkdirs(fs, filesDir, mapredSysPerms);
- String[] fileArr = files.split(",");
- for (String tmpFile: fileArr) {
- URI tmpURI;
- tmpURI = new URI(tmpFile);
- Path tmp = new Path(tmpURI);
- Path newPath = copyRemoteFiles(fs,filesDir, tmp, job, replication);
- URI pathURI = getPathURI(newPath, tmpURI.getFragment());
- DistributedCache.addCacheFile(pathURI, job);
- DistributedCache.createSymlink(job);
- }
- }
- if (libjars != null) {
- FileSystem.mkdirs(fs, libjarsDir, mapredSysPerms);
- String[] libjarsArr = libjars.split(",");
- for (String tmpjars: libjarsArr) {
- Path tmp = new Path(tmpjars);
- Path newPath = copyRemoteFiles(fs, libjarsDir, tmp, job, replication);
- DistributedCache.addArchiveToClassPath
- (new Path(newPath.toUri().getPath()), job, fs);
- }
- }
- if (archives != null) {
- FileSystem.mkdirs(fs, archivesDir, mapredSysPerms);
- String[] archivesArr = archives.split(",");
- for (String tmpArchives: archivesArr) {
- URI tmpURI;
- tmpURI = new URI(tmpArchives);
- Path tmp = new Path(tmpURI);
- Path newPath = copyRemoteFiles(fs, archivesDir, tmp, job, replication);
- URI pathURI = getPathURI(newPath, tmpURI.getFragment());
- DistributedCache.addCacheArchive(pathURI, job);
- DistributedCache.createSymlink(job);
- }
注意,MapReduce作业文件的上传和下载是通过DistributedCache工具完成的,它是一个数据分发工具。用户指定的文件会被分发到各个TaskTracker上以运行Task。这里暂不涉及该工具的细节,留待日后讨论。
- String originalJarPath = job.getJar();
- if (originalJarPath != null) { // copy jar to JobTracker's fs
- // use jar name if job is not named.
- if ("".equals(job.getJobName())){
- job.setJobName(new Path(originalJarPath).getName());
- }
- Path submitJarFile = JobSubmissionFiles.getJobJar(submitJobDir);
- job.setJar(submitJarFile.toString());
- fs.copyFromLocalFile(new Path(originalJarPath), submitJarFile);
- fs.setReplication(submitJarFile, replication);
- fs.setPermission(submitJarFile,
- new FsPermission(JobSubmissionFiles.JOB_FILE_PERMISSION));
- }
注意,在每次上传一种类型的文件后,都会将这种文件的路径配置到JobConf对象中,具体的工作由
- DistributedCache.addCacheFile(pathURI, job);
- DistributedCache.addArchiveToClassPath(new Path(newPath.toUri().getPath()), job, fs);
- DistributedCache.addCacheArchive(pathURI, job);
- job.setJar(submitJarFile.toString());
这四行代码完成。顺便提一句,Path类Hadoop文件系统在java.net.URI的基础上抽象了文件系统中的路径【3】。Java的File类和URL类分别抽象了不同的事物,Path可以说将二者统一起来。
3. 生成InputSplit文件
- // Create the splits for the job
- FileSystem fs = submitJobDir.getFileSystem(jobCopy);
- int maps = writeSplits(context, submitJobDir);
- jobCopy.setNumMapTasks(maps);
jobCopy是一个JobConf对象。其中,writeSplits方法会实际调用InputSplit.getSplits方法生成splits信息,并将splits原始信息和元信息写入HDFS对应的目录和文件中。有关split的生成过程日后研究,这里不展开了。最后,将作业对应的JobConf对象以XML配置文件形式写入到HDFS中:
- // Write job file to JobTracker's fs
- FSDataOutputStream out =
- FileSystem.create(fs, submitJobFile,
- new FsPermission(JobSubmissionFiles.JOB_FILE_PERMISSION));
- try {
- jobCopy.writeXml(out);
- } finally {
- out.close();
- }
至此,作业文件上传才算正式完毕。
接下来,作业将被提交到JobTracker,请关注下篇文章:
MapReduce调度与执行原理系列文章的更多相关文章
- MapReduce调度与执行原理之任务调度
前言 :本文旨在理清在Hadoop中一个MapReduce作业(Job)在提交到框架后的整个生命周期过程,权作总结和日后参考,如有问题,请不吝赐教.本文不涉及Hadoop的架构设计,如有兴趣请参考相关 ...
- MapReduce调度与执行原理之作业提交
前言 :本文旨在理清在Hadoop中一个MapReduce作业(Job)在提交到框架后的整个生命周期过程,权作总结和日后参考,如有问题,请不吝赐教.本文不涉及Hadoop的架构设计,如有兴趣请参考相关 ...
- MapReduce调度与执行原理之作业初始化
前言 :本文旨在理清在Hadoop中一个MapReduce作业(Job)在提交到框架后的整个生命周期过程,权作总结和日后参考,如有问题,请不吝赐教.本文不涉及Hadoop的架构设计,如有兴趣请参考相关 ...
- MapReduce调度与执行原理之任务调度(续)
前言 :本文旨在理清在Hadoop中一个MapReduce作业(Job)在提交到框架后的整个生命周期过程,权作总结和日后参考,如有问题,请不吝赐教.本文不涉及Hadoop的架构设计,如有兴趣请参考相关 ...
- FastDFS原理系列文章
FastDFS原理系列文章 基于FastDFS 5.03/5.04 2014-12-19 一.概述 FastDFS文档极少,仅仅能找到一些宽泛的架构文档,以及ChinaUnix论坛上作者对网友提问的一 ...
- Consul实现原理系列文章3: Consul的整体架构
工作中用到了Consul来做服务发现,之后一段时间里,我会陆续发一些文章来讲述Consul实现原理.在前几篇文章介绍完了Consul用到的两个关键性东西Raft和Gossip之后,这篇文章会讲述Con ...
- Consul实现原理系列文章2: 用Gossip来做集群成员管理和消息广播
工作中用到了Consul来做服务发现,之后一段时间里,我会陆续发一些文章来讲述Consul实现原理.这篇文章会讲述Consul是如何使用Gossip来做集群成员管理和消息广播的. Consul使用Go ...
- Consul实现原理系列文章1: 用Raft来实现分布式一致性
工作中用到了Consul来做服务发现,之后一段时间里,我会陆续发一些文章来讲述Consul实现原理.在前一篇文章中,我介绍了Raft算法.这篇文章会讲讲Consul是如何使用Raft算法来实现分布式一 ...
- JSP的执行原理、JSP的内置对象、四大作用域解析、MVC模式理解>从零开始学JAVA系列
目录 JSP的执行原理.JSP的内置对象.四大作用域解析.MVC模式理解 JSP的执行原理 这里拿一个小例子来解析JSP是如何被访问到的 首先将该项目部署到tomcat,并且通过tomcat启动 通过 ...
随机推荐
- Android 报错:Conversion to Dalvik format failed: Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.
在android高版本开发环境(sdk 4.4)导入低版本(sdk 3.0)的工程时编译报错,报错信息如:Conversion to Dalvik format failed: Unable to e ...
- Linux时间子系统(五) POSIX Clock
一.前言 clock是timer的基础,任何一个timer都需要运作在一个指定的clock上来.内核中维护了若干的clock,本文第二章描述了clock的基本概念和一些静态定义的posix clock ...
- 仿<赶集生活>client启动动画效果
demo下载地址: http://yun.baidu.com/s/1i3wqEMh 由于前几年csdn泄露password的事件,导致我的账号被拿去发广告文章了,联系了管理员帮我把几篇广告文删掉,可是 ...
- 判断当前用户有无Administrator的权限
很方便的一个函数,有兴趣的看看! /************************************************************************/ /* 函数说明: ...
- [转]VTH changes in DC from Hspice
Hello, everyone. I’d like to know the threshold of the MOS transistor. And I found the “.print vth() ...
- php 仿thinkphp的sql类库
模仿thinkphp封装的类库 <?php /** * MySql操作类2015版 * 作者:咖啡兽兽 287962566@qq.com * 使用说明: * //包含文件 * inclode ' ...
- Git教程Git多人协作开发
Git可以完成两件事情: 1. 版本控制 2.多人协作开发 如今的项目,规模越来越大,功能越来越多,需要有一个团队进行开发. 如果有多个开发人员共同开发一个项目,如何进行协作的呢. Git提供了一个非 ...
- 【Android】11.4 Fragment及其生命周期
分类:C#.Android.VS2015: 创建日期:2016-02-22 一.简介 Android从3.0开始引入了fragment的概念,主要是为了支持在大屏幕上实现更为动态和灵活的UI设计,比如 ...
- 使用 NGINX 和 NGINX Plus 的 Ingress Controller 进行 Kubernetes 的负载均衡
运行和管理跨机器集群的大规模的容器微服务应用是一个极具挑战的任务.Kubernetes 提供了一个强大的容器编排解决方案,从而帮助我们迎接这个挑战.它包含了一些重要特性,比如容错,自动伸缩,滚动升级, ...
- java动态代理的两种方法
动态代理,有两种情况,第一种是有接口的情况下,你可以选择为jdk自带的动态代理的方式来编写程序,但你想要为一个实在的类编写动态代理的方式的话,这时候就必须选择一些开源的lib包,如cglib包,同时还 ...