Hadoop的调度器详解

Big Data

简述Hadoop的调度器

[TOC]

​ hadoop调度器的作用是将系统中空闲的资源按一定策略分配给作业。调度器是一个可插拔的模块,用户可以根据自己的实际应用要求设计调度器。Hadoop中常见的调度器有三种,分别为:

1、基于队列的FIFO(先进先出)

  1. Hadoop1.x 默认的资源调度器,是Hadoop最早应用的一种调度策略
  2. 可以简单的将其理解为一个Java队列,它的含义在于集群中同时只能有一个作业在运行
  3. 将所有的Application按照提交时候的顺序来执行,只有当上一个Job执行完成之后后面的Job才会按照队列的顺序依次被执行。
  4. FIFO调度器以集群资源独占的方式来运行作业,这样的好处是一个作业可以充分利用所有的集群资源,但是对于运行时间短,重要性高或者交互式查询类的MR作业就要等待排在序列前的作业完成才能被执行,这也就导致了如果有一个非常大的Job在运行,那么后面的作业将会被阻塞。
  5. 因此,虽然单一的FIFO调度实现简单,但是对于很多实际的场景并不能满足要求。这也就催发了Capacity调度器和Fair调度器的出现。

基于队列的FIFO(先进先出)

2、容器调度器Capacity Scheduler

  1. Hadoop2.x 默认的容器调度器
  2. Capacity调度器也就是日常说的容器调度器
  3. 支持多个对列,这个队列的资源是用户自己去配置,然后每个采用FIFO的方式调度
  4. 为了防止容一个用户的Job任务独占队列中的资源,调度器会对同一用户提交的Job任务所占的资源进行限制
  5. 分配新的Job任务时,首先计算每个对列中正在运行的task个数与其队列应该分配的资源量做比值,然后选择比值最小的队列
    • 队列A有15task,20%的资源,那么比值就是15%0.2 = 70
    • 队列B有25task,50%的资源,那么比值就是25%0.5 = 50
    • 队列C有25task,30%的资源,那么比值就是25%0.3 = 80.33
    • 故,在分配新的Job任务时,会选择队列B
  6. 其次,按照Job任务的优先级和时间顺序,同时要考虑到用户的资源量和内存的限制,对队列中的Job任务进行排序执行
  7. 对各队列同时按照任务队列内的先后顺序依次执行,故有A、B、C三个Job分别在各自队列中的第一位,三个Job就同时执行
Capacity调度器特性:
  • 层次化的队列设计,这种层次化的队列设计保证了子队列可以使用父队列设置的全部资源。这样通过层次化的管理,更容易合理分配和限制资源的使用
  • 容量保证,队列上都会设置一个资源的占比,这样可以保证每个队列都不会占用整个集群的资源
  • 安全,每个队列又严格的访问控制。用户只能向自己的队列里面提交任务,而且不能修改或者访问其他队列的任务
  • 弹性分配,空闲的资源可以被分配给任何队列。当多个队列出现争用的时候,则会按照比例进行平衡
  • 多租户租用,通过队列的容量限制,多个用户就可以共享同一个集群,同事保证每个队列分配到自己的容量,提高利用率
  • 操作性,Yarn支持动态修改调整容量、权限等的分配,可以在运行时直接修改。还提供给管理员界面,来显示当前的队列状况。管理员可以在运行时,添加一个队列;但是不能删除一个队列。管理员还可以在运行时暂停某个队列,这样可以保证当前的队列在执行过程中,集群不会接收其他的任务。如果一个队列被设置成了stopped,那么就不能向他或者子队列上提交任务了
  • 基于资源的调度,协调不同资源需求的应用程序,比如内存、CPU、磁盘等等
相关参数的配置
  • capacity:队列的资源容量(百分比)。 当系统非常繁忙时,应保证每个队列的容量得到满足,而如果每个队列应用程序较少,可将剩余资源共享给其他队列。注意,所有队列的容量之和应小于100。
  • maximum-capacity:队列的资源使用上限(百分比)。由于存在资源共享,因此一个队列使用的资源量可能超过其容量,而最多使用资源量可通过该参数限制。(这也是前文提到的关于有任务运行的队列可以占用的资源的最大百分比)
  • user-limit-factor:每个用户最多可使用的资源量(百分比)。比如,假设该值为30,则任何时刻,每个用户使用的资源量不能超过该队列容量的30%。
  • maximum-applications :集群或者队列中同时处于等待和运行状态的应用程序数目上限,这是一个强限制,一旦集群中应用程序数目超过该上限,后续提交的应用程序将被拒绝,默认值为 10000。所有队列的数目上限可通过参数yarn.scheduler.capacity.maximum-applications设置(可看做默认值),而单个队列可通过参数yarn.scheduler.capacity..maximum- applications设置适合自己的值。
  • maximum-am-resource-percent:集群中用于运行应用程序
    ApplicationMaster的资源比例上限,该参数通常用于限制处于活动状态的应用程序数目。该参数类型为浮点型,默认是0.1,表示10%。所有队列的ApplicationMaster资源比例上限可通过参数yarn.scheduler.capacity. maximum-am-resource-percent设置(可看做默认值),而单个队列可通过参数
    yarn.scheduler.capacity..
    maximum-am-resource-percent设置适合自己的值。
  • state :队列状态可以为STOPPED或者 RUNNING,如果一个队列处于STOPPED状态,用户不可以将应用程序提交到该队列或者它的子队列中,类似的,如果ROOT队列处于STOPPED 状态,用户不可以向集群中提交应用程序,但正在运行的应用程序仍可以正常运行结束,以便队列可以优雅地退出。
  • acl_submit_applications:限定哪些Linux用户/用户组可向给定队列中提交应用程序。需要注意的是,该属性具有继承性,即如果一个用户可以向某个队列中提交应用程序,则它可以向它的所有子队列中提交应用程序。配置该属性时,用户之间或用户组之间用“,”分割,用户和用户组之间用空格分割,比如“user1, user2 group1,group2”。
  • acl_administer_queue:为队列指定一个管理员,该管理员可控制该队列的所有应用程序,比如杀死任意一个应用程序等。同样,该属性具有继承性,如果一个用户可以向某个队列中提交应用程序,则它可以向它的所有子队列中提交应用程序。

容量调度器Capacity Scheduler

3、公平调度器Fair Scheduler

  1. Fair调度器也就是日常说的公平调度器
  2. Fair调度器是一个队列资源分配方式,在整个时间线上,所有的Job平均的获取资源
  3. 默认情况下,Fair调度器只是对内存资源做公平的调度和分配。当集群中只有一个任务在运行时,那么此任务会占用整个集群的资源。当其他的任务提交后,那些释放的资源将会被分配给新的Job,所以每个任务最终都能获取几乎一样多的资源。
  4. 队列中的Job任务都是按照优先级分配资源,优先级越高分配的资源越多,但是为了确保每个Job任务都会分配到资源。优先级是根据每个Job任务的 理想获取资源量 - 实际获取资源量 差值 确定的,差值越大优先级越高

下面举例说明运行流程

  1. 公平调度器也可以在多个队列间工作
  2. 如下图所示,例如有两个用户A和B,他们分别拥有一个队列
  3. 当A启动一个Job而B没有任务提交时,A会获得全部集群资源
  4. 当B启动一个Job后,A的任务会继续运行,不过队列A会慢慢释放它的一些资源,一会儿之后两个任务会各自获得一半的集群资源
  5. 如果此时B再启动第二个Job并且其它任务也还在运行时,那么它将会和B队列中的的第一个Job共享队列B的资源,也就是队列B的两个Job会分别使用集群四分之一的资源,而队列A的Job仍然会使用集群一半的资源,结果就是集群的资源最终在两个用户之间平等的共享

Fair Scheduler实例

相关参数的配置

(1)yarn.scheduler.fair.allocation.file: “allocation”文件的位置,“allocation”文件是一个用来描述queue以及它们的属性的配置文件。这个文件必须为格式严格的xml文件。如果为相对路径,那么将会在classpath下查找此文件(conf目录下)。默认值为“fair-scheduler.xml”。

(2)yarn.scheduler.fair.user-as-default-queue:是否将与allocation有关的username作为默认的queue name,当queue name没有指定的时候。如果设置成false(且没有指定queue name) 或者没有设定,所有的jobs将共享“default”
queue。默认值为true。

(3)yarn.scheduler.fair.preemption:是否使用“preemption”(优先权,抢占),默认为fasle,在此版本中此功能为测试性的。

(4)yarn.scheduler.fair.assignmultiple:是在允许在一个心跳中,发送多个container分配信息。默认值为false。

(5)yarn.scheduler.fair.max.assign:如果assignmultuple为true,那么在一次心跳中,最多发送分配container的个数。默认为-1,无限制。

(6)yarn.scheduler.fair.locality.threshold.node:一个float值,在0~1之间,表示在等待获取满足node-local条件的containers时,最多放弃不满足node-local的container的机会次数,放弃的nodes个数为集群的大小的比例。默认值为-1.0表示不放弃任何调度的机会。

(7)yarn.scheduler.fair.locality.threashod.rack:同上,满足rack-local。

(8)yarn.scheduler.fair.sizebaseweight:是否根据application的大小(Job的个数)作为权重。默认为false,如果为true,那么复杂的application将获取更多的资源。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!