Hadoop中MapReduce运行剖析-Anatomy of a MapReduce Job Run with Hadoop
来源:互联网 发布:远程教学用什么软件 编辑:程序博客网 时间:2024/06/07 11:45
HINT: 本文是我在查询Hadoop具体运行过程中无意间看到的一篇文章,感觉写的挺详细而且不累赘,便翻译过来.原文作者本身就是Apache组织的一员,所以觉得可信度和准确度应该相对而言较高.才疏学浅,有翻译不对的地方望指正.另附原文地址,想进一步学习的同学可以戳这里Anatomy of a MapReduce Job Run with Hadoop
==============================================================================
你可以用一行简单的代码: JobClient.run(conf)来运行一个MapReduce的Job. 它非常短, 但是隐瞒了很多处理的过程. 这一章的内容将会揭露这些Hadoop运行Job中的步骤.
整个过程显示在图1中. 从最高级别的视角来看,整个步骤可以分为四个独立的实体(entity).
1. Client 用于提交MapReduce Job
2. JobTracker 用于协调整个Job的运行. 其本质上来说是一个Java应用,主类名为 JobTracker.
3. TaskTracker 用于运行由Job分割成的Tasks. 其本质亦是Java应用,主类名为TaskTracker.
4. Distributed Filesystem 分布式文件系统. 用于在不同的实体之间共享Job文件.
Figure 1. Hadoop 是怎么运行一个MapReduce Job
Figure 1. Hadoop 是怎么运行一个MapReduce Job
Job Submission (Job提交)
JobClient中的runJob()方法是一个很方便的方法,它可以创建一个新的JobClient实例并且调用这个新建实例中的submitJob()方法(图1中的step 1). 当提交过一个Job之后, runJob方法会每秒轮询(poll)一下这个Job的运行情况.如果运行情况从上一次报告之后有更新的话,就报告最新的情况给控制台(console). 当任务完成之后,如果此任务成功完成,那么整个job counter(job计数器)都会被显示出来(这里应该指的是每次运行完job之后屏幕给出的那些信息). 否则,造成job失败的错误会被登记在控制台的记录上.
JobClient的submitJob()方法通过以下步骤来实现job的提交过程:
1. 向JobTracker申请一个新的Job ID(通过调用JobTracker上的getNewJobID()方法).(图1中的step 2).
2. 检查此Job的输出详述. 举个例子,如果一个Job的输出目录还没有被定义或者已经存在的话,这个Job就不会被提交,而且会抛出一个异常给MapReduce程序.
3. 为一个Job计算其输入片. 如果这些输入片无法被计算的话,这里我们假设这个问题是由输入路径不存在导致的,那么这个Job就不会被提交,而且会抛出一个异常给MapReduce程序.
4. 复制运行此Job所需的资源-包括这个Job的JAR文件,配置文件和计算过的输入片-到此JobTracker的文件系统下的一个用此Job ID命名的目录下.Job的JAR文件会被复制数次,这个次数我们称之为replication factor,由 mapred.submit.replication控制,默认为10. 因此,在job运行的过程中,那些TaskTracker可以从cluster中很多地方获取这个JAR文件(图1中的step 3).
5. 通过调用JobTracker上的submitJob()来告诉JobTracker此Job已就绪(图1中的step 4).
Job Initialization(Job初始化)
当JobTracker接收到一个调用其submitJob()方法的请求时,它会把这个请求放到一个内在队列里. 此队列用于Job调度器挑选和初始化Job. 初始化包含创建一个代表Job运行的对象,其内部封装了此job的tasks和用于跟踪这些tasks的状态和进度的书签信息(图1中的step 5).
为了创建将要运行的task列表, Job调度器首先检索由JobClient从共享的文件系统中计算出的输入片(图1中的step 6). 然后, 它为每个输入片创建一个map task. 而reduce task的数量则是由JobConf中的mapred.reduce.tasks属性来决定的,此属性可以通过setNumReduceTasks()方法来设置, 然后调度器就只需简单地创建这个数目的reduce tasks就可以了.在这个时候,每个task会被给予它们的ID.
Task Assignment(Task分配)
TaskTracker通过一个简单的循环从而周期性的发送心跳信号给JobTracker. 这些心跳信号可以告诉JobTracker这个TaskTracker是处在Alive状态(也就是有效的), 但同时它们也是一个传输信息的通道. 在心跳信息中,一个TaskTracker将会指明它自身是否就绪从而运行一个新的task;如果就绪,则JobTracker将会通过心跳信息中的返回值与其通信并分配给它一个task(图1中的step 7).
在分配task给TaskTracker之前,JobTracker必须先选择一个job从而选择其task.本章后部分会介绍不同种类的调度算法,但是默认的方法就是一个简单的job优先级.选择一个job之后,JobTracker接着挑选此job中的一个task.
TaskTracker有固定数目的空位给map task和reduce task: 举个例子,一个tasktracker可能可以同时运行两个map task和两个reduce task.默认的调度器在map task空位和reduce task空位都空闲的情况下,会优先填充map task空位.也就是说,如果一个tasktracker有至少一个空闲的map task空位,jobtracker就会先选择一个map task;否则,它会选择一个reduce task.
在选择一个reduce task的时候, jobtracker只需简单地从就绪的reduce task 列表中选择下一个就可以(list of yet-to-be-run reduce tasks),因为它不需考虑数据本地性. 但是对于一个map task来说,它需要先考虑tasktracker的网内位置,然后选择一个所需输入跟其相近的任务给这个tasktracker.在最优情况下,此task是data-local性的,即运行此task的结点上有其所需的输入片;其次优先情况下,是rack-local性的,即运行此task的结点和输入片所在的结点在同一个rack上.其他既不是data-local亦不是rack-local性的任务则需要从其他不同的rack上检索所需输入片.你可以从job计数器上分辨这些种类的tasks.
Task Execution(Task 运行)
现在,一个tasktracker已经被分配给了一个task,下一步就是运行这个task. 首先,tasktracker从共享的文件系统上复制此job的JAR文件到本地的文件系统上.同时它也复制其他所需的文件(图1中的step 8). 第二步,为这个task创建一个本地的工作目录,同时把JAR包中的内容解压到这个目录下. 第三步,创建一个TaskRunner实例来运行此task.
TaskRunner创建一个新的Java虚拟机(图1中的step 9)来运行每个task(图1中的step 10),这样任何在用户定义的map和reduce功能中出现的bug将不会影响到tasktracker(举例子来说,将不会导致它崩溃或挂起).所以它可以在tasks中重复利用此JVM.
子进程通过umbilical 接口来跟其父进程通信. 每隔几秒它会通过此方法来告诉父进程task的运行状况知道task完成.
Streaming and Pipes(流和管道)
Streaming和Pipes都运行特定的map和reduce task从而实现用户提供的可实现性目的并且与其交流.
Figure 2. 对于tasktracker和其child来说,Streaming 和 Pipes 的可行性
在Streaming中, Streaming tasks可以用任何语言写成, 其与进程通过标准输入和输出流来进行通信. 另一方面, Pipes tasks监听一个socket然后传递给C++ 进程一个其环境中的端口号,这样在开始时,此C++进程与其父辈Java Pipes task可以建立一个稳定的稳固的socket通信. 在这两种情况下,在task的运行过程中,java进程将其输入的key-value对传递给外部进程,外部进程通过用户自定义的map或reduce功能处理此key-value对,然后将输出的key-value对传回给java进程.从tasktracker的角度来看,就好像是一个tasktracker的子进程在运行map/reduce代码.
Progress and Status Updates(进展和状态更新)
MapReduce job是长时间运行的批处理任务,持续时间可能是从数分钟到几小时.因为其时间长度很重要,所以用户需要得到此job的运行过程进度.一个job和其tasks都有一个status,此状态包含了job或task的状态(举例来说,即是运行中,成功完成,失败),maps和reduces的运行过程,job计数器的值和一个状态信息.这些状态在job的运行过程中一直在改变,所以,它们怎么能从client得到通信反馈呢?
当一个task运行中的时候,它会记录它自身的进度,也就是task完成的百分比.对于map tasks来说,其完成进度即是其处理完的输入百分比.对于reduce tasks来说会有一点复杂,但是系统仍然可以估计出其完成处理的输入进度.系统将整个进程分成三个部分,对应shuffle中的三个阶段.举个例子来说,如果task在reducer阶段处理完了其输入的一半,那么则记为此task完成了5/6,因为它已经完成了copy和sort阶段,每个阶段记为1/3,而且还有一半的reducer阶段,共计5/6.
What Constitutes Progress in MapReduce?(什么构成了MapReduce?)
进度并不是总是可衡量的,但是它总是可以告诉Hadoop一个task在做一些事情.举个例子来说,一个正在输出记录的task就可以认为是有进度的.虽然它不能表达出已经完成的比例,因为不知道剩下的记录还有多少,即使是创造这些输出的task也不知道.
进度报告很重要,因为它可以告知Hadoop一个有进度的task并没有fail.下面的所有操作组成了进度:
1. 读入一个输入记录(mapper/reducer)
2. 写出一个输出记录(mapper/reducer)
3. 设置reporter上的状态描述(通过 Reporter的setStatus()方法)
4. 增加计数器的值(通过Reporter的incrCounter()方法)
5. 调用Reporter的progress()方法
Task也有一系列的计数器用来统计在task运行过程中出现的不同的事件,要么就是在框架中内置的那些时间,即map的输出记录数量,要么就是用户自定义的.
如果一个task报告了其进度,则它树起了一个flag来说明它的状态改变需要告诉tasktracker.这个flag每隔3秒会被一个独立的线程来检验.一旦被树立,则会立即告之tasktracker其当下状态.同时,tasktracker每隔5秒发送心跳信息给jobtracker(这是个最小值,其间隔是与集群的规模有关;对于规模较大的集群来说,间隔会更长一点),另外,tasktracker会把运行在其自身的所有task的状态附带在这个心跳信息中发送出去.计数器信息的发送频率会少一点,长于5秒,因为它们相对来说是会消耗更多的带宽.
jobtracker把这些更新汇合起来从而形成一个所有job以及其task状态的全局视角观察.最终,像在早前提到的,jobclient每秒轮询一次jobtracker来获得最新的状态.Client亦通过JobClient的getJob()方法来获得一个RunningJob实例,此实例包含了此job的所有状态信息.
方法调用过程变现在图3中.
Figure 3. 在MapReduce系统中状态更新的广播
Job Completion(任务完成)
当jobtracker收到一个信息提示其最后一个task完成之后,其会改变job的状态为"成功".然后,当jobclient轮询状态是,知晓这个job已经成功完成,它就会告之用户这个信息,并且通过runJob()方法来返回值.
如果被设置过发送HTTP通知,jobtracker亦会发送通知.它可以通过修改job.end.notification.url来实现.
最后,jobtracker清空此job所有的工作状态,并且告之tasktracker亦清空(比如,删除中间输出).
- Hadoop中MapReduce运行剖析-Anatomy of a MapReduce Job Run with Hadoop
- Hadoop Internals - Anatomy of a MapReduce Job
- Hadoop权威指南第4版第7章Anatomy of a MapReduce Job Run
- Hadoop-MapReduce Job本地运行流程
- Hadoop,MapReduce,JOB参数
- 【Hadoop】MapReduce Job Files
- hadoop运行到mapreduce.job: Running job后停止运行
- Creating Hadoop MapReduce Job with Spring Data Apache Hadoop
- Hadoop - MapReduce MRAppMaster-剖析
- Hadoop - MapReduce MRAppMaster-剖析
- Hadoop MapReduce 深入MapReduce Job 提交
- hadoop MapReduce Job失效模型
- hadoop MapReduce Job失效模型
- hadoop MapReduce Job失效模型
- 【Hadoop】MapReduce Job Submission Files
- hadoop配置Mapreduce job日志
- hadoop mapreduce的job的几种运行模式
- 运行hadoop的MapReduce示例,在Running job卡住
- 如何利用iText在java程序中生成PDF文件
- linux2.6调度器
- hdu 4549 M斐波那契数列 数论 矩阵
- Http常见错误
- 论分类(三)-感知器篇(续)
- Hadoop中MapReduce运行剖析-Anatomy of a MapReduce Job Run with Hadoop
- TCP参数设定说明
- JAVA虚拟机体系结构-------(深入Java虚拟机第五章总结)
- Myeclipse中同时改变一个类中相同的代码的方法
- python script 生成sql 进行多个数据库合并
- 有趣的C语言面试题
- java----正则表达式
- 解决:mongodb的permissions on /data/k0 are too open
- linux将tomcat安装成系统服务