一个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.notifica
tion.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.task
tracker.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 都需要重新提交