MapReduce多用户任务调度器——容量调度器(Capacity Scheduler)原理和源码研究
前言:为了研究需要,将Capacity Scheduler和Fair Scheduler的原理和代码进行学习,用两篇文章作为记录。如有理解错误之处,欢迎批评指正。
容量调度器(Capacity Scheduler)是Yahoo公司开发的多用户调度器。多用户调度器的使用场景很多,根据资料1的说法,Hadoop集群的用户量越来越大,不同用户提交的应用程序具有不同的服务质量要求(QoS):
1. 批处理作业:耗时较长,对完成时间没有严格要求。如数据挖掘、机器学习等应用。
2. 交互式作业:期望及时返回结果。如Hive等应用。
3. 生产性作业:要求一定量的的资源保证。如统计值计算、垃圾数据分析等。
传统的FIFO调度器不能满足应用对响应时间和资源的多样化要求,多用户多队列调度器应运而生。容量调度器即是其中被广泛应用的一种。
容量调度器以队列为单位划分资源,每个队列都有资源使用的下限和上限。每个用户也可以设定资源使用上限。一个队列的剩余资源可以共享给另一个队列,其他队列使用后还可以归还。管理员可以约束单个队列、用户或作业的资源使用。支持资源密集型作业,可以给某些作业分配多个slot(这是比较特殊的一点)。支持作业优先级,但不支持资源抢占。
这里明确一下用户、队列和作业之间的关系。Hadoop以队列为单位管理资源,每个队列分配到一定的资源,用户只能向一个或几个队列提交作业。队列管理体现为两方面:1. 用户权限管理:Hadoop用户管理模块建立在操作系统用户和用户组之间的映射之上,允许一个操作系统用户或者用户组对应一个或者多个队列。同时可以配置每个队列的管理员用户。队列信息配置在mapred-site.xml文件中,包括队列的名称,是否启用权限管理功能等信息,且不支持动态加载。队列权限选项配置在mapred-queue-acls.xml文件中,可以配置某个用户或用户组在某个队列中的某种权限。权限包括作业提交权限和作业管理权限。2. 系统资源管理:管理员可以配置每个队列和每个用户的可用资源量信息,为调度器提供调度依据。这些信息配置在调度器自己的配置文件(如Capacity-Scheduler.xml)中。关于每个配置文件的常见内容见附录。
二、整体架构总体来说,容量调度器的工作流程分5个步骤:
1. 用户提交作业到JobTracker。
2. JobTracker将提交的作业交给Capacity Scheduler的监听器JobQueuesManager,并将作业加入等待队列,由JobInitializationPoller线程初始化。
3. TaskTracker通过心跳信息要求JobTracker为其分配任务。
4. JobTracker调用Capacity Scheduler的assignTasks方法为其分配任务。
5. JobTracker将分配到的任务返回给TaskTracker。
接下,我们结合源代码依次研究上述过程。
三、实现细节1. 调度器的启动回忆一下,前面谈到调度器启动是由JobTracker调用调度器的start方法实现的,首先来看start方法:
public boolean scheduleOffSwitch(int numTaskTrackers) { long missedTaskTrackers = getNumSchedulingOpportunities(); long requiredSlots = Math.min((desiredMaps() - finishedMaps()), numTaskTrackers); return (requiredSlots * localityWaitFactor) < missedTaskTrackers; }localityWaitFactor表示作业输入数据所在结点数占结点总数的比例,requiredSlots表示作业还需要的资源数,二者的乘积来衡量跳过次数的上限,而missedTaskTrackers即为跳过次数。missedTaskTrackers每次分配任务时都会增加,如果分配到本地任务,则返回任务,该变量会重置为0;若没有分配到,则表示跳过一次。在分配到非本地性任务后跳过次数也会重置为0。
下一篇文章计划学习Fair Scheduler。如有错误和问题,欢迎批评指正。
2013年10月7日