一个job的运行,涉及4个实体:客户端,JobTracker,TaskTracker,HDFS

【TaskTracker】 定时发送 heartbeat 给JobTracker 。heartbeat 用于报告 Tasktracker是否还存活。同时会通知JobTracker 本结点是否可以运行task ,如果可以运行Task, JobTracker 会分配一个Task到当前结点。

【客户端】使用Job.submit()提交任务,任务提交后。
1 向 jobtracker 请求一个新的作业ID (JobTracker.getNewJobId())
2 检查输出目录,例如输出目录已经存在,就不提交
3 计算作业的输入数据分片。如果分片无法计算(输入路径不存在),就不提交
4 将运作所需要的资源(Jar文件,配置文件,输入分片)复制到 jobtracker 的一个以Job id命名的目录下【HDFS】。jar文件有多个副本(由 mapred.submit.replication 定义,默认10个)
5 告知 jobtracker 作业准备执行,通过调用 JobTracker.submitJob()实现。
【JobTracker】 接收到JOB调用后,会把Job放入一个内部队列,作业调度器会从其中选择Job,并对其初始化。
作业调度器首先从HDFS中获得数据分片信息。为每个数据分片创建一个map task。reduce task数目由mapred.reduce.tasks 确定或通过job.setNumReduceTasks设置。除了map
和 reduce 任务,还会创建2个任务:a job setup task 和 a job cleanup task。
【TaskTracker】 定时发送 heartbeat 给JobTracker 。heartbeat 用于报告 Tasktracker是否还存活。同时会通知JobTracker 本结点是否可以运行task ,如果可以运行Task, JobTracker 会分配一个Task到当前结点。
Tasktracker中有固定数目的Map Task Slots(任务槽)
和 Reduce Task Slots。例如一个Tasktracker 配置同时运行2个map Task 和2个reduce Task 。JobTracker
会先分配Map task,如果Map Task Slot 没有空余,才会分配Reduce task 。
如果是分配Reduce Task,Job Tracker 只是简单的从列表中选择一个。如果分配的是map Task,还需要考虑输入数据。
tasktracker 被分配一个任务后,首先把Jar文件复制到本地文件系统,同时会将所需要的全部文件从分布式缓存复制到本地磁盘。tasktracker会新建一个本地工作目录,把Jar文件解压到这个文件夹。最后新建一个TaskRunner 运行任务。TaskRunner 会启动一个单独的JVM
运行任务。
进度和状态是通过heartbeat来更新和维护的。
如果 一个 task 报告进度,会设置一个标志位, tasktracker 中有一个单独进程每3分钟查询一次状态。tasktracker 每5分钟会向JobTracker提交一次状态,包括tasktracker上的所有task状态。JobTracker 会合并所有TaskTracker 的状态。
客户端可以通过Job.getStatus() 获得状态
Job Completion
当Job完成后,JobTracker会收一个Job Complete的通知,并将当前的Job状态更新为Successful,同时JobClient也会轮循获知提交的Job已经完成,将信息显示给用户。最后,JobTracker会清理和回收该Job的相关资源,并通知TaskTracker进行相同的操作(比如删除中间结果文件)。
可以设置 job.end.notification.url 属性,当Job
完成后,会通知相应的http 地址。
Job 处理失败,分为3种情况: task 失败, tasktracker 失败,jobtracker 失败。
【task 失败】因用户代码问题,导致map 或 reduce task 失败。子任务JVM
进程会在退出之前向 tasktracker 发送错误报告。本次 task 被标记为failed,并释放 slot 运行另一个task。如果一个task 间隔10分钟没有更新进度。tasktracker
会将任务标记为failed,之后 task 进程被自动杀死。可以通过属性mapred.task.timeout 设置超时时间(毫秒)
当jobtracker接到一个 task 失败的通知后,会重新调度task运行。如果一个task 失败4次或更多,就不会再重新执行这个task。可以通过属性mapred.map.max.attempts 和 mapred.reduce.max.attempts 定义重试次数。
默认,任何tast 失败超过定义的最大重试次数后,整个job就会失败。在实际应用中,有时并不想因为某个tast一直失败导致整个job失败。可以通过设置属性 mapred.max.map.failures.percent 和 mapred.max.reduce.failures.percent
【Tasktracker 失败】如果一个Tasktracker 超过10分钟没有发送heartbeats。可以通过属性mapred.tasktracker.expiry.interval 设置(毫秒),jobtracker
会从任务池中移除Tasktracker。重新调度这个Tasktracker 中的所有任务。
如果一个Tasktracker 上有超过4个task失败
(mapred.max.tracker.failures),jobtracker 会记录当前Tasktracker 失败,如果一个Tasktracker
有超过4次失败(mapred.max.tracker.blacklists),jobtracker 会把当前Tasktracker 加入黑名单。被加入黑名单的Tasktracker 不会在被分配任务,但之前完成的task的输出可以继续使用。被加入黑名单的Tasktracker 重启后可以重新加入集群。
【jobtracker 失败】是非常严重的失败。Hadoop 没有办法处理这种失败。重启jobtracker后,所有未完成的Job 都需要重新提交