Yarn资源调度器

            Yarn资源调度器

                                     作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

 

 

  YARN是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于一个分布式的操作系统平台,而MapReduce,Spark,Flink邓运算程序则相当于运行于操作系统之上的应用程序。

 

一.YARN基本架构

  如下图所示,YARN主要由ResourceManager、NodeManager、ApplicationMaster和Container等组件构成。

  ResourceManager(简称RM):
    全局的资源管理器,负责整个各系统的资源管理和分配,它带了FIFO,Capacity Schedule,Fair Schedule三种常用调度器。
    RM的主要作用如下:
      (a)处理客户端请求;
      (b)监控NodeManager;
      (c)启动或监控ApplicationMaster;
      (d)资源的分配与调度;

  NodeManager(简称NM):
    每个节点上的资源和任务管理器,定时向RM汇报本节点上的资源以及使用情况和各个Container的运行状态,接收并处理来自AM的Container启动/停止等各种请求。
    NM的主要作用如下:
      (a)管理单个节点上的资源;
      (b)处理来自ResourceManager的命令;
      (c)处理来自ApplicationMaster的命令

  ApplicationMaster(简称AM):
    用户提交的每个应用程序均包含一个AM,它与RM调度器协商以获取资源分配给内部的任务;与NM通信以启动/停止任务;监控所有的任务运行状态,并在任务运行失败时为任务申请资源以重启任务。
    AM的主要作用如下:
      (a)负责数据的切分;
      (b)为应用程序申请资源并分配给内部的任务;
      (c)任务的监控与容错;

  Container:
    YARN中的资源抽象,它封装了某个节点上的多维度资源,如内存,CPU,磁盘,网络,运行环境(如job.xml)等,当AM向RM申请资源时,RM为AM返回的资源是用Continer表示的。YARN回味每个任务分配一个Container且该任务只能使用该Container中描述的资源。

 

二.YARN的运行原理

  (1)MapReduce程序提交到客户端所在的节点。
  (2)
YarnRunner向ResourceManager申请一个Application。
  (3)
RM将该应用程序的资源路径返回给YarnRunner。
  (4)
该程序将运行所需资源提交到HDFS上。
  (5)
程序资源提交完毕后,申请运行mrAppMaster。
  (6)
RM将用户的请求初始化成一个Task。
  (7)
其中一个NodeManager领取到Task任务。
  (8)
该NodeManager创建容器Container,并产生MRAppmaster。
  (9)
Container从HDFS上拷贝资源到本地。
  (10)
MRAppmaster向RM申请运行MapTask资源。
  (11)
RM将运行MapTask任务分配给另外两个NodeManager,另两个NodeManager分别领取任务并创建容器。
  (12)
MR向两个接收到任务的NodeManager发送程序启动脚本,这两个NodeManager分别启动MapTask,MapTask对数据分区排序。
  (13)
MrAppMaster等待所有MapTask运行完毕后,向RM申请容器,运行ReduceTask。
  (14)
ReduceTask向MapTask获取相应分区的数据。
  (15)
程序运行完毕后,MR会向RM申请注销自己。

 

三.作业提交流程

  1>.作业提交
    (1)Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。
    (2)Client向RM申请一个作业id。
    (3)RM给Client返回该job资源的提交路径和作业id。
    (4)Client提交jar包、切片信息和配置文件到指定的资源提交路径。
    (5)Client提交完资源后,向RM申请运行MrAppMaster。

  2>.作业初始化
    (6)当RM收到Client的请求后,将该job添加到容量调度器中。
    (7)某一个空闲的NM领取到该Job。
    (8)该NM创建Container,并产生MRAppmaster。
    (9)下载Client提交的资源到本地。

  3>.任务分配
    (10)MrAppMaster向RM申请运行多个MapTask任务资源。
    (11)RM将运行MapTask任务分配给另外两个NodeManager,另两个NodeManager分别领取任务并创建容器。

  4>.任务运行
    (12)MR向两个接收到任务的NodeManager发送程序启动脚本,这两个NodeManager分别启动MapTask,MapTask对数据分区排序。
    (13)MrAppMaster等待所有MapTask运行完毕后,向RM申请容器,运行ReduceTask。
    (14)ReduceTask向MapTask获取相应分区的数据。
    (15)程序运行完毕后,MR会向RM申请注销自己。

  5>.进度和状态更新
    YARN中的任务将其进度和状态(包括counter)返回给应用管理器, 客户端每秒(通过mapreduce.client.progressmonitor.pollinterval设置)向应用管理器请求进度更新, 展示给用户。

  6>.作业完成
    除了向应用管理器请求作业进度外, 客户端每5秒都会通过调用waitForCompletion()来检查作业是否完成。时间间隔可以通过mapreduce.client.completion.pollinterval来设置。作业完成之后, 应用管理器和Container会清理工作状态。作业的信息会被作业历史服务器存储以备之后用户核查。

 

四.资源调度器概述

  如下图所示,Hadoop作业调度器主要有三种:FIFO、Capacity Scheduler和Fair Scheduler。

  我们可以通过修改yarn-site.xml文件的"yarn.resourcemanager.scheduler.class"来修改你使用那种调度器,在Hadoop 2.x版本中默认使用的是Capacity Scheduler

1>.先进先出调度器(FIFO)

  FIFO生产环境中很少有人使用,不能实现更高级的调度策略,比如优先级,层级等策略均不支持。

  FIFO队列优点:    
    简单,即按照job到达时间排序,先到达先服务。
  FIFO队列缺点:
    会存在一个巨大的任务阻塞整个队列。

  举个例子:
    以学校住宿舍打水的场景为例,有10个人排队大水,第一个人同时拿了8个电壶打水,其余9人没人拿1个电壶打水,但是第一个人严重阻塞大家打水的效率。

2>.容量调度(Capacity Scheduler)

  容量调度器简单点就是多个FIFO调度器同时运行。它缓解了FIFO的缺点,但并不灵活。

  Capacity Scheduler队列优点:
    (1)支持多个队列,每个队列可配置一定的资源量,每个队列采用FIFO调度器并行运行;
    (2)为了防止同一个用户的作业独占队列中的资源,该调度器会对同一个用户提交的作用所占资源量进行限定;
    (3)每个队列中正在运行的任务数与应该分得的计算资源之间的比值,选择一个该比值最小的队列(即分配一个最闲的队列给最新提交的job),按照作业优先级和提交时间顺序,同时考虑用户资源啦限制和内存限制队列任务排序。

  Capacity Scheduler队列缺点:
    灵活性差,一个job被分配到一个队列后其它队列的资源无法给该队列使用。

  举个例子:
    还是假设10个人打水,此时有3个打水的地方,第一个人拿了8个壶打水,其余九人都拿了一个壶。但此时第一个人同时只能使用一个位置,其它2个位置要让给其余9人打水,当拿九个人打完水后其余2个位置空余了,但第一个人并不允许使用空余的位置资源,因为它同时只能占用一个位置,其余位置就算空着也不能用,空着的位置是为了等其它同学来打水。

3>.公平调度器(Fair Scheduler)

  公平调度器实在容量调度器的基础之上又做了升级,它优化了容量调度器不灵活的缺陷。每个对类中的job按照优先级分配资源,优先级越高分配的资源越多,但是每个job都会分配到资源以确保公平。

  在资源有限的情况下,每个job理想情况下获得的计算资源与实际获得的计算资源存在一种差距,这个差距叫做缺额。在同一个对类中,job的资源缺额越大,越有限获得资源有限执行。作业时按照缺额的高低来先后执行的。

  Fair Scheduler优点:
    支持多队列多用户,每个队列中的资源量可以配置,同一队列中的作业公平共享队列中所有资源。
    假设有根队列下有4个队列分别为A,B,C,D。我们假设这4个队列中分配的资源是相同的,即每个队列各占整个集群的25%资源,我们此时手动又为A划分了两个子队列E,F我们假设它们2个队列分配的资源相同,即分别栈整个集群的12.5%,当一个集群正在运行时,如果我们job提交到A,B.C.D任何一个队列该job理论上可以支配25%的集群资源,如果我们将该job手动分配到E或者F队列,那么此时他回去的资源仅有12.5$的集群资源。
  Fair Scheduler缺点:
    每个队列都有一个最小资源占比的参数,假设根队列有5个队列,此时有5个job分配在5个队列在执行,我们假设队列的最小资源占比是20%,此时往根下的第六个队列提交任务是不可行的,需要等待其它队列释放资源。

  举个例子:
    还是说上面打水的案例,当第一个人拿8个壶去打水时,如果发现3个位置都是空的,它可以一个人同时占用3个位置打水,当有第二个同学来打水时,他会主动让出一个位置,当有第三个同学来打水时,他会继续让出一个位置,当第四个同学来打水时,他不会让他了,因为他最少得有一个位置来打水。相对来说这种场景更符合我们生活规律。

  温馨提示:
    公平调度器适合用于集群资源比较紧张的大数据集群,需要你对集群的资源做相应的规划,如果你的集群资源比较充裕,基本上默认的容量调度器也够使用了。身为一个大数据运维工程师,我推荐大家生产环境中使用公平调度器,这样可以充分利用集群资源。尤其是老板跟你说没钱买机器的时候,你就得硬着头皮来搞集群调度器优化了。

 

五.任务推测执行

1>.作业完成时间取决于最慢的任务完成时间

  一个作业由若干个Map任务和Reduce任务构成。因硬件老化、软件Bug等,某些任务可能运行非常慢。系统中有99%的Map任务都完成了,只有少数几个Map老是进度很慢,完不成,怎么办?建议查看YARN的WebUI相应的日志信息以便于定位问题。其次就是开启任务推测执行机制。

2>.推测执行机制

  发现拖后腿的任务,比如某个任务运行速度远慢于任务平均速度。为拖后腿任务启动一个备份任务,同时运行。谁先运行完,则采用谁的结果。

3>.执行推测任务的前提条件 

  (a)每个Task只能有一个备份任务
  (b)
当前Job已完成的Task必须不小于0.05(5%)   (c)开启推测执行参数设置。mapred-site.xml文件中默认是打开的。

  mapred-site.xml开启推测执行参数如下:
    mapreduce.map.speculative:
      如果为true,则可以并行执行某些MapTask的多个实例。

    mapreduce.reduce.speculative
      如果为true,则可以并行执行某些MapTask的多个实例。

4>.不能启用推测值机制情况

  (a)任务间存在严重的负载倾斜;
 
  (b)特殊任务,比如任务向数据库中写数据。

  温馨提示:
    除了上述两种情况外,在集群的资源比较吃紧的时候,建议关闭推测执行机制,因为推测任务执行其实时需要付出资源代价的。

5>.推测执行算法原理

  假设某一时刻,任务T的执行进度为progress,则可通过一定的算法推测该任务的最终完成时刻estimateEndTime。

  另一方面,如果此可为该任务启动一个备份任务,则可推断出他可能的完成时可estimateEndTime,于是可读出以下几个公式:
    推测运行时间(estimateTunTime)   =  (当前时刻(currentTimestamp    - taskStartTime(任务启动时刻)))  /  任务运行比例(progress)
    推测执行完成时刻(estimateEndTime) =  推测运行时间(estimateTunTime) + taskStartTime(任务启动时刻)
    备份任务推测完成时刻(estimateEndTime) =  当前时刻(currentTimestamp) + 运行完成任务的平均时间(averageRunTime)

  温馨提示:
    (a)MR总是选择(estimateEndTime - estimateEndTime)差值最大的任务,并为之启动备份任务;
    (b)为了防止大量任务同时启动备份任务造成的资源浪费,MR为每个作业设置了同时启动的备份任务数目上限;
    (c)推测执行机制实际上采用了经典的优化算法:"以空间换时间"。他同时启动多个相同任务处理相同的数据,并让这些任务竞争以缩短数据处理时间。显然,这种方法需要占用更多的计算资源。在集群资源紧缺的情况下,应合理使用该机制,争取在少量资源的情况下,减少作业的计算时间;

 

posted @ 2020-05-05 22:34  JasonYin2020  阅读(339)  评论(0编辑  收藏  举报