3.6 资源调度器ResourceScheduler
RM中最重要的活跃服务提供者应该是“资源调度器(scheduler)”,这是个实现了ResourceScheduler界面的某类对象,通过createScheduler()创建,具体的类型则在配置文件中加以指定。注意这里所说的只是资源调度,实际上也是对于“作业(Job)”投运的调度,这跟操作系统中进程/线程的运行调度是两码事。Hadoop提供了三种不同的资源调度器供选用,用户可以在配置文件中加以选择。这三种调度器是:
(1)FifoScheduler。这是最简单的调度器,其调度策略就是“先来先走”、“先来先给”,按次序来。
(2)FairScheduler。这种调度器要考虑公平的问题,不让属于同一用户的作业独占资源。
(3)CapacityScheduler。这是最复杂的调度器,还要考虑尽量合理地使用各个节点的资源。
配置文件yarn-sire.xml中有一条“yarn.resourcemanager.scheduler.class”,就是用于这个目的。如果不加规定,则默认的调度器DEFAULT_RM_SCHEDULER是CapacityScheduler。不过,从理解Hadoop的结构和运行流程的角度,这三者并无太大的不同,所以本书在涉及调度器时都以最简单的FifoScheduler为例,有兴趣或需要的读者可以自己分析一下另外两个调度器的代码。
调度当然不能是无米之炊,调度器手里的资源只能来自集群中的众多NodeManager节点。为此,ResourceManager内部有个ResourceTrackerService类的对象resourceTracker,它跟踪管理着NodeManager节点所知道的资源变动。另有一个NodesListManager类的对象nodesListManager则维持着一个节点清单,记录着哪些节点当前是可用的,哪些则是不可用的。而ResourceTrackerService和NodesListManager所掌握的信息,则来自众多NodeManager节点的心跳报告,即伴随着每次“心跳”提供的报告。这些信息,最终都要汇集到资源调度器,因为这些资源都要由资源调度器分配出去。
有了“家底”,调度器就可以应各个作业组长AM的要求通过allocate()分配资源、通过assignContainers()指派容器了。作业完成计算以后,还要通过completedContainer()回收容器。
对于ResourceManager内部的这些成分,以及其他一些成分,后面将结合具体的情景和流程加以介绍。
创建了前述的那么多活跃服务,完成了初始化之后,RM,即当前的Active RM,便可坐等客户上门了。至于作为Standby的RM,如果有的话,则不用创建这些活跃服务,只需要做好公共部分的初始化就行了;但是要做好准备,因为随时都可能需要接管Active RM的角色,那时候就要创建这些活跃服务了。