Hadoop.MapReduce作业任务
当我们只用几行代码就可以运行一个MapReduce作业时,我们是否知道其实里面隐藏着大量的执行细节.本文就是来揭示一个Hadoop运行作业的执行细节.
运行MapReduce作业的过程将包含以下四个实体
1. 客户端.提交hadoop作业
2. 分布式文件系统(一般为HDFS),
3. JobTracker.协调作业的运行
4. TaskTracker运行作业划分后的任务
客户端提交作业:
1. 向JobTracker请求一个新的作业ID.
2. JobTracker检查作业的输出.如果没有指定输出目录和输出目录不存在,作业就不提交
3. JobTracker计算作业分片,如果分片无法计算.比如输入路径不存在,作业就不提交
4. 将运行作业所需的资源(包括Jar文件,配置文件和计算所得额输入分片)复制到一个以作业ID命名的JobTracker文件系统的目录下,作业jar的副本较多(可配置).因此在运行作业的任务时,集群中有多个副本可以供TaskTracker访问
初始化作业:
JobTracker接收到作业时,会将其放入一个内部队列中,交由作业调度器进行调度,并对其初始化.初始化包括创建一个表示正在运行作业的对象---封装任务及记录信息.以便跟踪任务的状态和过程.
为了创建任务运行列表,作业调度器首先获取作业分片信息,然后为每个分片创建一个map任务.创建的reduce任务由配置指定.任务的ID在此时指定
任务的分配:
TaskTracker运行一个简单的循环来定期发送”心跳”给JobTracker. ”心跳”告知JobTracker,自己是否还存活,同时也充当两者之间的消息通道.作为心跳的一部分, TaskTracker会指明自己是否准备好运行新的任务.如果是, JobTracker会为它分配一个任务,并使用”心跳”的返回值与TaskTracker进行通信.
对于map任务和reduce任务, TaskTracker有固定数量的任务槽,准确数量由TaskTracker核的数量和内存的大小来决定,默认调度器在处理reduce任务槽之前,会填满空闲的map任务槽.因此如果TaskTracker有一个空闲的map任务槽, JobTracker会为它选择一个map任务,.否则选择一个reduce任务
为选择一个reduce任务, JobTracker简单地从待运行的reduce任务列表中选取一个来执行,用不着考虑数据本地化.然而,对于一个map任务, JobTracker会考虑TaskTracker的网络位置,并选取一个距离输入分片文件最近的TaskTracker.在理想情况下,任务是数据本地化的.
任务的执行:
1.从共享文件系统把作业的jar文件复制到TaskTracker所在的文件系统,从而实现作业的jar文件本地化.同时TaskTracker将应用程序所需的全部文件从分布式缓存复制到本地磁盘,
2.TaskTracker为任务新建一个本地工作目录.并把jar文件的内容解压到该文件夹下.
3.TaskTracker新建一个TaskRunner实例来运行任务.每个新的TaskRunner启动一个新的JVM来运行每个任务.以便每个map和reduce的运行问题都不会引起TaskTracker 崩溃.但在不同任务之间重用JVM还是有可能的
4.子进程通过umbilical接口与父进程通信,任务的子进程每隔几秒便告知父进程它的进度,直到任务完成
作业的进度和状态更新:
1.一个作业和和它的每个任务都有一个状态,包括:作业和任务的状态,map和reduce的进度,作业计数器的值,状态消息或描述.这些信息在作业期间不断改变. 对map任务,任务进度是已处理输入所占的比例.对reduce任务,情况稍微复杂,但系统仍然会估计已处理的reduce输入的比例.
2.每个任务都有一组计数器,负责对任务运行过程中各个事件进行计数.如果任务已经报告了进度,便会设置一个标志以表明状态变化将被送到TaskTracker,有个独立的线程会每隔3秒检查一次此标志,同时每隔5秒, TaskTracker 会发送”心跳”到JobTracker.由于TaskTracker运行的所有任务的状态都会在调用中被发送至JobTracker,计数器的发送时间通常少于5秒.因为计数器占用的带宽通常较高, JobTracker将这些更新合并起来,产生一个表明所有作业及其所含任务状态的全局视图.客户端通过每秒查询JobTracker来接收最新状态.
作业的完成:
当JobTracker收到最后一个任务已经完成的通知后,便把作业的状态设为”成功”,然后客户端查询到状态,任务完成.
作业的故障处理:
在实际应用中,往往会存在用户代码存在错误,进程崩溃,机器出故障等情况,hadoop的最主要的好处就是它能处理此类故障并完成作业
map和reduce的代码抛出异常:
这种情况下,子任务JVM会在退出之前向其父TaskTracker发送错误报告,错误报告最后被计入任务日志,.TaskTracker会将此次task attempt标记为failed,释放一个任务槽来运行另外一个任务.
JVM Bug导致jvm退出:
此种情况TaskTracker会注意到进程已经退出,并将此次尝试标记为failed.任务失败的超时时间通常为10分钟.如果超时时间设定为0则将永远不会超时,挂起的任务槽永远不会被释放,最终降低整个集群的效率
JobTracker知道一个任务执行失败后,会重新调度该任务的执行,.JobTracker会避免重新调度失败过的TaskTracker的上的任务槽.如果一个任务失败的次数超过4次,整个作业都会失败.
TaskTracker的失败:
一个TaskTracker由于崩溃或运行过于缓慢而失败, JobTracker注意到后会将它从等待任务调度的TaskTracker池中移除.如果是未完成的作业, JobTracker会安排此TaskTracker上已经运行并成功完成的map任务重新运行.如果TaskTracker上面的失败任务数远高于集群的平均失败任务数,它将会被列入黑名单,可以通过重启从JobTracker黑名单中移除.
JobTracker失败:
JobTracker失败是所有失败中最严重的一种.目前Hadoop没有处理JobTracker失败的机制-它是一个单点故障.在此情况下,作业注定失败.未来版本可能通过多个JobTracker来解决这个问题,任何时候,只有一个主JobTracker.