分布式系统Hadoop源码阅读与分析(一):作业调度器实现机制
上一篇博文对Hadoop的作业调度器进行了介绍,我们知道,JobTracker和TaskTracker是Hadoop作业调度过程中最核心的两个部分,前者负责map/reduce作业的调度与分派,后者负责map/reduce作业的实际执行,它们之间通过RPC机制进行通讯。下面将对Hadoop 0.20.2版本中作业调度相关源码进行分析,至于JobTracker和TaskTracker中与作业调度无关的源码部分,并未进行详细介绍。
1. JobTracker部分
1.1 JobTracker
JobTracker是作业调度的控制类,实现了InterTrackerProtocol和TaskTrackerManager接口(当然,还有其他接口,这里我们只关心调度相关的接口),维护一个TaskScheduler的实例,并托管其生命周期。
在JobTracker的主方法中,首先,构造JobTracker实例对象,在此过程中,TaskScheduler实例会伴随JobTracker一起被构造,另外,通过RPC,构造RPC服务器interTrackerServer;当完成JobTracker的构造后,接着给JobTracker的TaskScheduler类型变量taskScheduler设置TaskTrackerManager实例字段为当前的JobTracker实例。然后,调用JobTracker的offerService方法开始提供服务。
JobTracker.heartbeat方法主要是TaskTracker端远程调用时用到的方法,其主要作用就是分派具体任务(将Task封装成LaunchTaskAction),并将封装后的Task分发到TaskTracker端。
1.2 TaskScheduler
TaskScheduler是作业调度器的抽象基类,实现了Configurable接口,具体的实现有JobQueueTaskScheduler和LimitTasksPerJobTaskScheduler。
在TaskScheduler中,通过维护Configuration和TaskTrackerManager成员变量,实现对作业队列中所有Job的调度过程,具体见assignTasks方法。
1.3 JobQueueTaskScheduler
JobQueueTaskScheduler继承于TaskScheduler,为Hadoop中的默认调度器,实现FIFO调度队列,作业队列按优先级和提交时间进行排序。
1.4 LimitTasksPerJobTaskScheduler
LimitTasksPerJobTaskScheduler继承于JobQueueTaskScheduler,在JobQueueTaskScheduler基础上,可以对每个Job的Task总数作限制。
1.5 TaskTrackerManager
TaskTrackerManager接口用于管理运行中的Cluster的所有TaskTracker信息,它被JobTracker实现,同时供TaskScheduler调度使用。
1.6 InterTrackerProtocol
InterTrackerProtocol接口是JobTracker和TaskTracker之间通信的协议接口, JobTracker作为RPC调用的Server端,实现InterTrackerProtocol接口,供TaskTracker远程调用。
1.7 Configurable
Configurable接口用于配置Configuration对象。
2.
TaskTracker部分
2.1 TaskTracker
Task的执行实际是由TaskTracker发起的,TaskTracker会定期(缺省为3秒钟,参见MRConstants类中定义的HEARTBEAT_INTERVAL变量)与JobTracker进行一次通信,报告自己Task的执行状态,接收JobTracker的指令等,TaskTracker里面会通过循环的方式查找。
2.2 TaskTrackerStatus
TaskTrackerStatus是TaskTracker的状态类,记录了TaskTracker的资源使用情况。
2.3 HeartbeatResponse
HeartbeatResponse是心跳回复信息类,记录了经TaskTracker发出的心跳,由JobTracker处理后产生的回复信息。
2.4 TaskTrackerAction
TaskTrackerAction记录TaskTracker的action,它有四个子类,分别是KillJobAction、KillTaskAction、LaunchTaskAction和CommitTaskAction。
2.5 TaskTracker$TaskInProgress
TaskInProgress是TaskTracker的内部类,它主要负责对每个执行中的Task任务的监控和具体调度。
2.6 TaskTracker$TaskLauncher
TaskLauncher是个继承于Thread的TaskTracker的内部类,在这里面会维护一个TaskInProgress的链表:
private List<TaskInProgress> tasksToLaunch;
该列表中的每个TaskInProgress 实例对应一个TaskUnit任务。
该类的run方法才是主体关键之处,它会循环判断是否tasksToLaunch中有新任务要做,有就从该列表中拿出来,然后去调用TaskTracker.startNewTask(TaskInprogress)去开启一个新任务。
2.7 Task
Task为抽象类,代表任务,它有两个子类:MapTask 和 ReduceTask。
2.8 TaskRunner
TaskRunner为Task的执行类,它有两个子类:MapTaskRunner和ReduceTaskRunner。
3.
RPC过程
3.1 RPC.getServer()
RPC服务端接口。为指定协议的实例,在指定的地址和端口上启动服务。
3.2 RPC.waitForProxy()
RPC客户端接口,创建一个指定服务端的代理。