深入分析hadoop之YARN原理、架构、作业流程及调度器

一、YARN的原理

1.1、yarn是什么?

首先看一下官方对于这个词汇的解释:Apache Hadoop YARN (Yet Another Resource Negotiator,另一种资源协调者)是一种新的 Hadoop 资源管理器,它是一个通用资源管理系统,可为上层应用提供统一的资源管理和调度,在Hadoop2引入,为集群在利用率、资源统一管理和数据共享等方面带来了巨大好处。

划重点,这里我们需要记住通用、统一、hadoop2引入利用率、资源统一管理和数据共享这些关键词。

接下来,我们看一下它的官方描述图:

yarn官方图
看完这个图,在结合刚才的关键词。这些既然是它的特点,那它的架构设计一定是围绕着这些方面进行的,既然是hadoop2引入的,那一定是因为hadoop1的资源管理器有些问题需要解决。让我们带着问题,接着往下看。

1.2、yarn解决了什么问题?

yarn是在hadoop2引入的,将JobTracker的两个主要功能(资源管理和作业调度/监控)分离,因此我们先看一下在hadoop1中,jobTracker有哪些问题或者说局限性:

  1. 与MapReduce深度耦合:起初资源调度的设计就是围绕hadoop自家的MapReduce进行的,因此耦合度较高,不支持其它计算框架;
  2. 难以扩展:由于jobTracker同时要进行资源管理和作业调度,压力较大,已经是hadoop1时期整个系统性能的瓶颈;
  3. 可靠性差:由于采用的是master/slave结构,master很容易出现单点故障,且不支持高可用配置;
  4. 资源利用率低:jobTracker是一种基于槽位的资源分配模型,由于槽位是一种粗粒度的资源划分单位,所以通常一个任务不会用完一个槽位的资源,hadoop1分为map slot和reduce slot,而它们之间资源也不共享,因此会造成一些资源浪费。

其实yarn的设计就是用来解决这些问题的,yarn使用了一个全局的资源管理器ResourceManager和与每个应用对应的ApplicationMaster,Resourcemanager和NodeManager一起协同组成了一个全新的通用系统,可以用分布式的方式管理应用程序。

1.3、yarn有哪些特点?

了解特点前先来看一张图:
yarn支持多种计算框架并行

这张图足够阐述了yarn的强大作用,正是yarn在hadoop2的彻底重构,才使得它在大数据整个体系中始终占据着举足轻重的地位。

yarn的特点可以概括如下:

  1. 支持多应用并行:yarn的一个很重要的改进就是拓展了Hadoop,使得它不仅支持MapReduce计算,还支持众多别的计算应用,比如我们常用的spark on yarn;
  2. 可扩展性
  3. 支持高可用
  4. 提高资源利用率

二、架构设计详解

从yarn的整体上来看,依然属于master/slave结构模型,它主要依赖三个组件来运行,第一个是ResourceManager(全局的资源管理器),作为整个集群资源的老大,它主要包括两部分:scheduler用于调度,ApplicationManager用于管理集群中的用户作业。第二个是NodeManager,它位于每个节点上负责管理该节点的用户作业和工作流,同时还会不断发送自己的Container的使用情况给ResourceManager。最后一个组件是ApplicationMaster,负责管理用户作业的整个生命周期,主要功能是向ResourceManager申请计算资源(containers)并且会和NodeManager进行交互来执行和监控具体的task。

整体的架构设计图如下:
yarn各组件关系

2.1、ResourceManager(简称RM)

RM是一个全局的资源管理器,拥有系统所有资源的分配决定权,负责整个系统的资源管理和分配。包括处理客户端请求、启动和监控ApplicationMaster、监控NodeManager、资源的分配与调度。需要与每个节点上的NodeManager和每一个应用程序的ApplicationMaster协调工作。

RM的主要职责是调度,也就是在相互竞争的应用程序之间分配系统的可用资源,它并不关注每个应用程序的状态。

它主要由两个组件构成:调度器(Scheduler)和应用程序管理器(ApplicationManager)。

2.1.1、调度器(Scheduler)

关于调度器我们先知道总结它的作用,由于它的重要性,我们后面会着重去分析。

scheduler是一个纯粹的调度器,可插拔, 根据容量、队列等限制条件给各个运行中的应用分配资源,保障整个集群的运行效率。

需要注意的是,调度器仅根据各个应用程序的资源需求进行资源分配,而资源分配单位用一个抽象概念“资源容器”(Resource Container,简称Contrainer)表示,Container是一个动态资源分配单位,它将内存、cpu、磁盘、网络等资源封装在一起,从而限定每个任务使用的资源量。

它不再从事任何与具体应用程序相关的工作,比如不负责监控或者跟踪应用的执行状态,也不负责重新启动因应用执行失败或者硬件故障而产生的失败任务,这些均交由应用程序相关的ApplicationMaster完成。

2.1.1、应用程序管理(ApplicationManager)

ApplicationManager主要负责管理整个系统中所有应用程序,包括应用程序提交,与调度器协商资源以启动ApplicationMaster监控ApplicationMaster运行状态并在失败时重启ApplicationMaster运行的Container等。

2.2、NodeManager(简称NM)

NM相当于是RM的"区域代理商",这个区域指的是节点,它管理着hadoop集群中独立的计算节点,主要负责与RM通信,负责启动和管理应用程序的container的生命周期,监控它们的资源使用情况(主要是cpu和内存),同时跟踪节点的监控状态,管理日志等,并会给RM进行报告。

  • NM在启动时,NM向RM注册,然后发送心跳包来等待RM的指令,主要目的是管理RM分配给它的应用程序container。NM只负责管理自身的Container,其实它并不知道运行在它上面的应用的信息;
  • NM在在运行时期,通过NM和RM协同工作,这些信息会不断被更新并保障整个集群发挥出最佳状态。

详细职责总结:

  1. 接收RM的请求,给应用的某个任务分配Container;
  2. 和RM交换信息以确保整个集群平稳运行,其实全局的RM就是通过收集每个NM的报告信息来追踪整个集群健康状态的,而NM负责监控自身的健康状态即可;
  3. 管理每个Container的生命周期;
  4. 管理每个节点上的日志;
  5. 执行Yarn上面应用的一些额外的服务,比如MapReduce的shuffle过程

对MapReduce的shuffle部分感兴趣的可以查看我上一篇文章:深入分析MapReduce之Shuffle原理和数据处理流程

2.2.1、container

相信学过docker的一定不会对container陌生,本质上container是容器的意思,在yarn里它代表框架的计算单元, 是具体执行应用task(如map task、reduce task)的基本单位。Container和集群节点的关系是:一个节点会运行多个Container,但一个Container只会存在一个节点内,不会跨节点。

其实每个Container就是一组分配的系统资源,现阶段只包含两种系统资源(cpu和内存)(之后可能会增加磁盘、网络、GPU等资源),由NodeManager监控,Resourcemanager调度。

每一个应用程序从ApplicationMaster开始,它本身就是一个container(第0个),一旦启动,ApplicationMaster就会更加任务需求与Resourcemanager协商更多的container,在运行过程中,可以动态释放和申请container。

2.3、ApplicationMaster(简称AM)

AM负责和scheduler协商合适的container,然后跟踪应用程序的状态,并监控它们进度。AM是协调集群中应用程序执行的进程,因此每个应用程序都有自己的AM,负责与RM协商资源(container)并和NM协同工作来执行和监控任务 。

当一个ApplicationMaster启动后,会周期性的向RM发送心跳报告来确认其健康和所需的资源情况,在建好的需求模型中,AM在发往RM的心跳信息中会封装自己的偏好和限制。在随后的心跳答应中,AM会收到集群中特定的节点上绑定了一定资源的container的租约,而且根据RM发来的container,AM可以更新它的执行计划以适应资源不足或者过剩,因此container可以动态的分配和释放资源。

三、作业调度流程详解

yarn作业调度流程
在我们掌握了yarn的架构设计之后,我们需要从客户端提交作业开始,从头到尾的理清楚yarn的作业调度流程,这不仅有助于我们对yarn资源调度的学习,其实对以后深入理解spark on yarn也是有益的。

下面我们分步骤解析整个作业调度流程(会合并部分图示步骤,以突出重点):

  1. 首先客户端向ResourceManager提交应用并请求一个ApplicationMaster实例;

  2. 收到请求后,ResourceManager给客户端应答一个applicationID以及有助于客户端请求资源的资源容量信息;

  3. ResourceManager找到可以运行一个Container的NodeManager,并在这个Container中启动ApplicationMaster实例;

    这个过程具体流程:

    1. Application Submission Context发出响应,其中包含有:ApplicationID,用户名,队列以及其他启动ApplicationMaster的信息,
      Container Launch Context(CLC)也会发给ResourceManager,CLC提供了资源的需求,作业文件,安全令牌以及在节点启动ApplicationMaster所需要的其他信息;
    2. 当ResourceManager接收到客户端提交的上下文,就会给ApplicationMaster调度一个可用的container(我们称之为container0);
    3. 然后ResourceManager就会联系NodeManager启动ApplicationMaster,并建立ApplicationMaster的RPC端口和用于跟踪的URL,用来监控应用程序的状态。
  4. ApplicationMaster向ResourceManager进行注册,注册成功之后客户端就可以查询ResourceManager获得自己ApplicationMaster的详细信息。也就是说可以和自己的ApplicationMaster直接交互了。(在注册响应中,ResourceManager会发送关于集群最大和最小容量信息)

  5. 通常情况下,ApplicationMaster是根据resource-request协议向ResourceManager发送resource-request请求的,此时ResourceManager会根据调度策略尽可能最优的为ApplicationMaster分配container资源,并作为资源请求的应答发送给ApplicationMaster;

  6. 如果Container分配成功,ApplicationMaster就会通过向NodeManager发送container-launch-specification信息来启动Container( container-launch-specification信息包含了能够让Container和ApplicationMaster交流所需要的资料),一旦container启动成功之后,ApplicationMaster就可以检查他们的状态,Resourcemanager也不再参与程序的执行,只负责处理调度和监控其他资源,并且Resourcemanager可以命令NodeManager杀死container;

  7. 就和docker里的容器类似,应用程序的代码会在启动的Container中运行,并会把运行的进度、状态等信息通过application-specific协议发送给ApplicationMaster。随着作业的不断执行,ApplicationMaster也会不断的将心跳和进度信息发给ResourceManager,需要注意的是,在这些心跳信息中,ApplicationMaster还可以请求和释放一些container;

  8. 此时提交应用的客户端主动和ApplicationMaster进行交流以获得应用的运行状态、进度更新等信息(交流的协议同样是application-specific协议);

  9. 当应用程序和所有相关工作已经执行完成,ApplicationMaster会向ResourceManager取消注册然后关闭,然后会把用到的所有的Container归还给系统,在每个container被杀死或者被回收时,Resourcemanager都会通知NodeManager聚合日志并清理container专用的文件。至此,整个作业调度流程结束。

四、调度器详解

在前面分析ResourceManager的时候,已经介绍了scheduler调度器,但是由于它的重要性,我决定把它单独拿出来分析。

4.1、调度器分类

调度器主要分为三类:FIFO Scheduler(先进先出调度器)、Capacity Scheduler(容量调度器)、Fair Sceduler(公平调度器)

我们常用的hadoop2.7版本的资源调度器默认是Capacity Scheduler

4.2、FIFO Scheduler分析

FIFO Scheduler
就像我们学数据结构时候的FIFO一样,在调度器里FIFO Scheduler也是一个先进先出的队列。它把任务按照提交的顺序排成一个队列,在进行资源分配的时候,先把资源分配给最顶部的任务,如果最顶部的任务的资源需求得到了满足才会分配给下一个任务。因此,会导致其它任务被阻塞,通常情况下同一时间只有一个任务在执行,在实际生产环境里一般不会用这种调度器。

4.3、Capacity Scheduler分析

默认的资源调度器。会把任务分为多个队列,同时每个队列内部先进先出,同一时间队列中只有一个任务在执行,队列的并行度等于队列的个数,如果使用容量调度器就可以进行yarn资源队列配置。
Capacity Scheduler

  1. 支持多个队列,每个队列可配置一定的资源量,每个队列采用FIFO调度策略;

  2. 为了防止同一个用户的作业独占队列中的资源,该调度器会对同一用户提交 的作业所占资源量进行限定;

  3. 首先,计算每个队列中正在运行的任务数与其应该分得的计算资源之间的比 值,选择一个该比值最小的队列(最闲的);

  4. 其次,按照作业优先级和提交时间顺序,同时考虑用户资源量限制和内存限 制对队列内任务排序;

  5. 三个队列同时按照任务的先后顺序依次 执行,比如,job11、job21和job31分别排在 队列最前面,先运行,也是并行运行。

4.4、Fair Scheduler分析

公平调度器和它的名字一样,设计目标就是为所有的应用分配公平的资源,而这个公平是我们可以通过参数来设置的。它也是有多个队列,但是每个队列内部是按照缺额大小来分配资源并启动任务的。也就是同一队列中的作业公平共享队列中所有资源,同一时间队列中可以有多个任务执行,所以队列的并行度大于等于队列的个数。
Fair Scheduler

什么是缺额?

在资源有限的情况下,每个job理想情况下获得的计算资源与实际获得的计算资源存在一种差距,这个差距就叫做缺额。

比如有三个队列:queueA、queueB和queueC,每个队列中的job按照优先级分配资源,优先级越高分配的资源越多,但是每个 job 都会分配到资源以确保公平。

在同一个队列中,job的资源缺额越大,越先获得资源优先执行。作业是按照缺额的高低来先后执行的,所以可以看到上图有多个作业同时运行。

发布了102 篇原创文章 · 获赞 173 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/qq_26803795/article/details/104964345