JobTracker节点对Task实例状态报告的处理
来源:互联网 发布:win10 cmd java 编辑:程序博客网 时间:2024/06/06 08:42
前面谈到过,每一个TaskTracker节点都要在它向JobTracker节点发送心跳包的时候顺带报告运行在其上的Task的状态信息,这些Task是指正在TaskTracker节点上运行的,或者从上一次报告到现在的时间间隔中完成的或者是失败的任务。JobTracker节点之所以需要收集这些正在执行或者刚完成的任务的状态信息,是因为它要及时掌握各个作业的执行进度,一方面将此报告给用户,一方面还调整作业的任务调度,如任务的意外处理,任务/作业的善后处理等。这里说的任务的意外处理包括,对于失败的任务或者是拖后退的任务需要从新安排其它的TaskTracker节点来执行等,详细情况我会在后面再作介绍。
对于JobTracker节点处理TaskTracker发送过来的Task状态报告的详细过程,我将结合源代码来阐述。但在此之前,我想先介绍一下相关的几个概念:作业/作业实例、任务/任务实例。作业指的是用户提交的作业,用Job的实例对象来表示,作业实例指的是Job运行的状态信息,用JobInProgress的实例对象来表示;任务指的是该任务的执行进度状态信息,用TaskInProgress的实例对象来表示,任务实例则指的是在将该任务交由某一个TaskTacker节点执行的任务,用TaskAttempID的实例对象来表示。一个作业对应一个作业实例,而一个任务可能对应多个任务实例,这是因为一个任务可能交给了多个TaskTracker节点来执行。JobTracker节点处理Task实例状态报告的源码如下:
void updateTaskStatuses(TaskTrackerStatus status) { String trackerName = status.getTrackerName(); for (TaskStatus report : status.getTaskReports()) { report.setTaskTracker(trackerName); TaskAttemptID taskId = report.getTaskID(); // expire it expireLaunchingTasks.removeTask(taskId); JobInProgress job = getJob(taskId.getJobID()); if (job == null) { // if job is not there in the cleanup list ... add it synchronized (trackerToJobsToCleanup) { Set<JobID> jobs = trackerToJobsToCleanup.get(trackerName); if (jobs == null) { jobs = new HashSet<JobID>(); trackerToJobsToCleanup.put(trackerName, jobs); } jobs.add(taskId.getJobID()); } continue; } if (!job.inited()) { // if job is not yet initialized ... kill the attempt synchronized (trackerToTasksToCleanup) { Set<TaskAttemptID> tasks = trackerToTasksToCleanup.get(trackerName); if (tasks == null) { tasks = new HashSet<TaskAttemptID>(); trackerToTasksToCleanup.put(trackerName, tasks); } tasks.add(taskId); } continue; } TaskInProgress tip = taskidToTIPMap.get(taskId); // Check if the tip is known to the jobtracker. In case of a restarted // jt, some tasks might join in later if (tip != null || hasRestarted()) { if (tip == null) { tip = job.getTaskInProgress(taskId.getTaskID()); job.addRunningTaskToTIP(tip, taskId, status, false); } // Update the job and inform the listeners if necessary JobStatus prevStatus = (JobStatus)job.getStatus().clone(); // Clone TaskStatus object here, because JobInProgress // or TaskInProgress can modify this object and // the changes should not get reflected in TaskTrackerStatus. // An old TaskTrackerStatus is used later in countMapTasks, etc. job.updateTaskStatus(tip, (TaskStatus)report.clone()); JobStatus newStatus = (JobStatus)job.getStatus().clone(); // Update the listeners if an incomplete job completes if (prevStatus.getRunState() != newStatus.getRunState()) { JobStatusChangeEvent event = new JobStatusChangeEvent(job, EventType.RUN_STATE_CHANGED, prevStatus, newStatus); updateJobInProgressListeners(event); } } else { LOG.info("Serious problem. While updating status, cannot find taskid " + report.getTaskID()); } // Process 'failed fetch' notifications List<TaskAttemptID> failedFetchMaps = report.getFetchFailedMaps(); if (failedFetchMaps != null) { for (TaskAttemptID mapTaskId : failedFetchMaps) { TaskInProgress failedFetchMap = taskidToTIPMap.get(mapTaskId); if (failedFetchMap != null) { // Gather information about the map which has to be failed, if need be String failedFetchTrackerName = getAssignedTracker(mapTaskId); if (failedFetchTrackerName == null) { failedFetchTrackerName = "Lost task tracker"; } failedFetchMap.getJob().fetchFailureNotification(failedFetchMap, mapTaskId, failedFetchTrackerName); } } } } }从上面的源代码可以看出,JobTracker节点对于每一个Task状态报告的处理考虑到了一些意外情况,这些意外情况主要包括:
1).Task实例所属的作业不在JobTracker节点的任务队列内。出现这个情况的可能原因是这个Task实例是一个拖后退的任务,当它完成时,该Task实例所属的Job早已被完成了,或者该Job被用户kill掉了。对于这种情况,JobTracker节点就直接让该TaskTracker把运行在其上的所有属于该Job的Task全部清除(这个TaskTracker节点上可能还运行有该Job的拖后腿任务)。
2).Task实例所属的作业还没有初始化(以前说过,没有被初始化的Job是不能被JobTracker节点调度执行的)。出现这种情况的一个可能的原因是TaskTracker节点刚刚重启过,在恢复作业的时候还没有来得及初始化该Job。对于这种情况,JobTracker节点就直接让该TaskTracker清除该任务。
3).Task实例所属的任务还没有被JobTracker节点调度执行。出现这种情况的一个可能的原因是JobTracker节点在该Task实例执行期间重启了,重启之后还没有来得及调度该任务。对于这种情况,JobTracker节点为了提高性能就认为该情况是还算是正常的,不过得先得通知该Task实例所属的Job实例。
4).对于Reduce Task实例的进度状态报告,它还会附带额外的报告信息,就是报告那些它无法fetch到map输出的Map任务,JobTracker节点需要将这些消息转告给该Task实例所属的作业实例,以便该Job实例能够及时调整其内部任务的调度。至于Job实例是如何处理的,并不是本文所要介绍的重点,不过我会在以后的博文中详细阐述。
在正常的情况下,JobTracker节点不会直接的处理这些Task实例的状态报告,而是将其交给它们所属的Job实例来处理,Job实例处理之后如果它的状态发生变化,JobTracker节点会通知对应的事件监听器。那么,Job实例又是如何根据它的一个Task实例状态来更新自己当前的状态呢?由于这个过程相当的复杂不适合于此时介绍。
- JobTracker节点对Task实例状态报告的处理
- Hadoop jobTracker taskTracker 与task 的联系
- JobTracker节点上的作业恢复RecoveryManager
- MapReduce(十四): JobTracker的心跳处理
- newlisp跟踪jobtracker状态
- Hadoop启动后Jobtracker一直是initializing状态的问题解决
- 点空白处,无法取消对节点的选中状态
- Android 对事物状态的处理方法
- 移动namenode、secondarynamenode和jobTracker的节点(使其成为独立节点)
- 短信发送状态报告(Status Report)的处理
- 短信发送状态报告(Status Report)的处理
- 短信发送状态报告(Status Report)的处理
- backlogs自定义task的状态
- 推荐的Scrum task状态
- task的几种状态
- MapReduce: JobTracker默认task scheduling策略
- kernel对D状态(TASK_UNINTERRUPTIBLE)task在120s不被调度的检测
- kernel对R状态task在4s不被调度的检测
- Hibernate中对于数据的(增删改查)操作的一个例子的代码
- 数据库中char, varchar, nvarchar的差异
- Eclipse开发C/C++之使用技巧小结,写给新手
- NSString获取子字符串:
- str_replace妙用之数组替换
- JobTracker节点对Task实例状态报告的处理
- Xcode4.2中将Three20开源库导入到工程项目中
- Python网页抓取urllib,urllib2,httplib[2]
- C语言溢出判断
- Android 获取系统或SDCARD剩余空间信息
- Nginx:取代Apache的高性能Web服务器
- POJ 2777 (线段树)
- Objective C 语法系列--异常处理
- SGU 101 Domino 里程碑2——开始刷sgu!