9、学习大数据笔记-Yarn资源调度系统

1,268 阅读28分钟

Hadoop 学习系列(三)之 YARN 详细解析

一、yarn介绍

Apache Hadoop YARN 是 apache Software Foundation Hadoop的子项目,为分离Hadoop2.0资源管理和计算组
件而引入。YARN的诞生缘于存储于HDFS的数据需要更多的交互模式,不单单是MapReduce模式。Hadoop2.0 的
YARN 架构提供了更多的处理框架,不再强迫使用MapReduce框架

从hadoop2.0 的架构图可以看出,YARN承担着原本由MapReduce承担的资源管理的功能,同时将这部分的功能
打包使得他们可以被新的数据处理引擎使用。这也同时简化了MapReduce的流程,使得MapReduce专注的将数据
处理做到最好。使用YARN,可以用共同的资源管理,在Hadoop上跑很多应用程序。目前,很多机构已经开发基于
YARN的应用程序。

当企业的数据在HDFS中是可用的,有多种数据处理方式是非常重要的。有了Hadoop2.0和YARN,机构可以采用流
处理、互动数据处理方式以及其他的基于Hadoop的应用程序。
当企业的数据在HDFS中是可用的,有多种数据处理方式是非常重要的。有了Hadoop2.0和YARN,机构可以采用流
处理、互动数据处理方式以及其他的基于Hadoop的应用程序。

YARN 提供了些什么? YARN从以下几个方面提升了Hadoop的计算能力: 
1、可扩展性 数据中心的数据处理能力
继续快速增长。因为YARN ResourceManager 仅仅专注于 调度,能将大集群的管理变得更加简单。 
2、兼容
MapReduce 现存的MapReduce 应用程序无需更改就能直接在YARN上运行 
3、提高集群使用率
ResourceManager 是一个纯粹的调度系统根据capacity ,fair 或者SlAs等原则对集群进行优化利用。与之前不同的
是,再也没有map slot和reduce slot,没有这两类资源的划分,有助于提高集群资源的利用。
4、支持MapReduce
以外的计算框架 数据处理除了图形处理和迭代处理,还为企业添加了一些实时处理模型,从而提升企业对Hadoop
投资回报率,
5、灵活 随着MapReduce 成为用户端库,它发展独立于底层的资源管理层,从而可以有多种灵活的
方式。

二、yarn架构

YARN的架构还是经典的主从(master/slave)结构,YARN服务由一个ResourceManager(RM)和多个NodeManager(NM)构成,ResourceManager为主节点(master),
NodeManager为从节点(slave)。

在YARN体系结构中,全局ResourceManager作为主守护程序运行,通常在专用计算机上运行,该仲裁程序在各种
竞争应用程序之间仲裁可用的群集资源。ResourceManager跟踪群集上可用的活动节点和资源的数量,并协调用
户提交的应用程序应获取这些资源的时间和时间。ResourceManager是具有此信息的单个进程,因此它可以以共
享,安全和多租户的方式进行分配(或者更确切地说,调度)决策(例如,根据应用程序优先级,队列容量,
ACL,数据位置等)。
当用户提交应用程序时,将启动名为ApplicationMaster的轻量级进程实例,以协调应用程序中所有任务的执行。
这包括监视任务,重新启动失败的任务,推测性地运行慢速任务以及计算应用程序计数器的总值。这些职责先前已
分配给所有工作的单个JobTracker。ApplicationMaster和属于其应用程序的任务在NodeManagers控制的资源容
器中运行。
NodeManager是TaskTracker的更通用和高效的版本。NodeManager没有固定数量的map和reduce插槽,而是有
许多动态创建的资源容器。容器的大小取决于它包含的资源量,例如内存,CPU,磁盘和网络IO。目前,仅支持内
存和CPU(YARN-3)。cgroups可能会在将来用于控制磁盘和网络IO。节点上的容器数量是配置参数和专用于从属
守护程序和OS的资源之外的节点资源总量(例如总CPU和总内存)的乘积。
有趣的是,ApplicationMaster可以在容器内运行任何类型的任务。例如,MapReduce ApplicationMaster请求容
器启动map或reduce任务,而Giraph ApplicationMaster请求容器运行Giraph任务。您还可以实现运行特定任务
的自定义ApplicationMaster,并以此方式创建一个闪亮的新分布式应用程序框架,该框架可以更改大数据世界。
我鼓励您阅读Apache Twill,它旨在简化编写位于YARN之上的分布式应用程序。
在YARN中,MapReduce简单地降级为分布式应用程序的角色(但仍然是非常流行且有用的),现在称为MRv2。
MRv2只是重新实现经典的MapReduce引擎,现在称为MRv1,它运行在YARN之上。
一个可以运行任何分布式应用程序的集群 ResourceManager,NodeManager和容器不关心应用程序或任务的类
型。所有特定于应用程序框架的代码都被简单地移动到其ApplicationMaster,以便YARN可以支持任何分布式框架
- 只要有人为它实现适当的ApplicationMaster。
由于这种通用方法,运行许多不同工作负载的Hadoop YARN集群的梦想成真。想象一下:数据中心内的单个
Hadoop集群可以运行MapReduce,Giraph,Storm,Spark,Tez / Impala,MPI等。
单集群方法显然具有许多优点,包括:

更高的集群利用率,一个框架未使用的资源可以被另一个框架使用 降低运营成本,因为只需要管理和调整一个“全
能”集群 减少数据移动,因为不需要在Hadoop YARN和运行在不同机器群集上的系统之间移动数据 管理单个群集
还可以为数据处理提供更环保的解决方案。使用的数据中心空间更少,浪费的硅更少,耗电更少,碳排放更少,因
为我们在更小但更高效的Hadoop集群上运行相同的计算。

核心组件

简单地说,YARN 主要由 ResourceManager、NodeManager、ApplicationMaster和 Container 等几个组件构
成。

组件名                              作用
ResourceManager           是Master上一个独立运行的进程,负责集群统一的资源管理、调度、分配等等;
ApplicationManager        相当于这个Application的监护人和管理者,负责监控、管理这个Application的所有Attempt在cluster中各个节点上的具体运行,同时负责向Yarn
ResourceManager           申请资源、返还资源等;
NodeManager               是Slave上一个独立运行的进程,负责上报节点的状态(磁盘,内存,cpu等使用信息);
Container                 是yarn中分配资源的一个单位,包涵内存、CPU等等资源,YARN以Container为单位分配资源;

ResourceManager 负责对各个 NadeManager 上资源进行统一管理和调度。当用户提交一个应用程序时,需要提
供一个用以跟踪和管理这个程序的 ApplicationMaster,它负责向 ResourceManager 申请资源,并要求
NodeManger 启动可以占用一定资源的任务。由于不同的 ApplicationMaster 被分布到不同的节点上,因此它们
之间不会相互影响。
Client 向 ResourceManager 提交的每一个应用程序都必须有一个 ApplicationMaster,它经过
ResourceManager 分配资源后,运行于某一个 Slave 节点的 Container 中,具体做事情的 Task,同样也运行与某
一个 Slave 节点的 Container 中。

2.1 ResourceManager
    RM是一个全局的资源管理器,集群只有一个,负责整个系统的资源管理和分配,包括处理客户端请求、启动/监控
    ApplicationMaster、监控 NodeManager、资源的分配与调度。它主要由两个组件构成:调度器(Scheduler)和
    应用程序管理器(Applications Manager,ASM)。
    (1) 调度器
    调度器根据容量、队列等限制条件(如每个队列分配一定的资源,最多执行一定数量的作业等),将系统中的资源
    分配给各个正在运行的应用程序。需要注意的是,该调度器是一个“纯调度器”,它从事任何与具体应用程序相关的
    工作,比如不负责监控或者跟踪应用的执行状态等,也不负责重新启动因应用执行失败或者硬件故障而产生的失败
    任务,这些均交由应用程序相关的ApplicationMaster完成。
    调度器仅根据各个应用程序的资源需求进行资源分配,而资源分配单位用一个抽象概念“资源容器”(Resource
    Container,简称Container)表示,Container是一个动态资源分配单位,它将内存、CPU、磁盘、网络等资源封
    装在一起,从而限定每个任务使用的资源量。
    (2) 应用程序管理器
    应用程序管理器主要负责管理整个系统中所有应用程序,接收job的提交请求,为应用分配第一个 Container 来运
    行 ApplicationMaster,包括应用程序提交、与调度器协商资源以启动 ApplicationMaster、监控
    ApplicationMaster 运行状态并在失败时重新启动它等。
    
2.2 ApplicationMaster
    管理 YARN 内运行的一个应用程序的每个实例。关于 job 或应用的管理都是由 ApplicationMaster 进程负责的,
    Yarn 允许我们以为自己的应用开发 ApplicationMaster。
    功能:
    数据切分;
    为应用程序申请资源并进一步分配给内部任务(TASK);
    任务监控与容错;
    负责协调来自ResourceManager的资源,并通过NodeManager监视容易的执行和资源使用情况。
    可以说,ApplicationMaster 与 ResourceManager 之间的通信是整个 Yarn 应用从提交到运行的最核心部分,是
    Yarn 对整个集群进行动态资源管理的根本步骤,Yarn 的动态性,就是来源于多个Application 的
    ApplicationMaster 动态地和 ResourceManager 进行沟通,不断地申请、释放、再申请、再释放资源的过程。

2.3 NodeManager

NodeManager 整个集群有多个,负责每个节点上的资源和使用。
NodeManager 是一个 slave 服务:它负责接收 ResourceManager 的资源分配请求,分配具体的 Container 给应
用。同时,它还负责监控并报告 Container 使用信息给 ResourceManager。通过和ResourceManager 配合,
NodeManager 负责整个 Hadoop 集群中的资源分配工作。
功能:NodeManager 本节点上的资源使用情况和各个 Container 的运行状态(cpu和内存等资源)
接收及处理来自 ResourceManager 的命令请求,分配 Container 给应用的某个任务;
定时地向RM汇报以确保整个集群平稳运行,RM 通过收集每个 NodeManager 的报告信息来追踪整个集群健
康状态的,而 NodeManager 负责监控自身的健康状态;
处理来自 ApplicationMaster 的请求;
管理着所在节点每个 Container 的生命周期;
管理每个节点上的日志;
执行 Yarn 上面应用的一些额外的服务,比如 MapReduce 的 shuffle 过程;
当一个节点启动时,它会向 ResourceManager 进行注册并告知 ResourceManager 自己有多少资源可用。在运行
期,通过 NodeManager 和 ResourceManager 协同工作,这些信息会不断被更新并保障整个集群发挥出最佳状
态。
NodeManager 只负责管理自身的 Container,它并不知道运行在它上面应用的信息。负责管理应用信息的组件是
ApplicationMaster

Container

Container 是 YARN 中的资源抽象,它封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等,当 AM 向
RM 申请资源时,RM 为 AM 返回的资源便是用 Container 表示的。YARN 会为每个任务分配一个 Container,且
该任务只能使用该 Container 中描述的资源。
Container 和集群节点的关系是:一个节点会运行多个 Container,但一个 Container 不会跨节点。任何一个 job
或 application 必须运行在一个或多个 Container 中,在 Yarn 框架中,ResourceManager 只负责告诉
ApplicationMaster 哪些 Containers 可以用,ApplicationMaster 还需要去找 NodeManager 请求分配具体的
Container。
需要注意的是,Container 是一个动态资源划分单位,是根据应用程序的需求动态生成的。目前为止,YARN 仅支
持 CPU 和内存两种资源,且使用了轻量级资源隔离机制 Cgroups 进行资源隔离。
功能:
    对task环境的抽象;
    描述一系列信息;
    任务运行资源的集合(cpu、内存、io等);
    任务运行环境

Resource Request 及 Container

Yarn的设计目标就是允许我们的各种应用以共享、安全、多租户的形式使用整个集群。并且,为了保证集群资源调
度和数据访问的高效性,Yarn还必须能够感知整个集群拓扑结构。
为了实现这些目标,ResourceManager的调度器Scheduler为应用程序的资源请求定义了一些灵活的协议,通过它
就可以对运行在集群中的各个应用做更好的调度,因此,这就诞生了Resource Request和Container。
一个应用先向ApplicationMaster发送一个满足自己需求的资源请求,然后ApplicationMaster把这个资源请求以
resource-request的形式发送给ResourceManager的Scheduler,Scheduler再在这个原始的resource-request中
返回分配到的资源描述Container。
每个ResourceRequest可看做一个可序列化Java对象,包含的字段信息如下:

<!--
- resource-name:资源名称,现阶段指的是资源所在的host和rack,后期可能还会支持虚拟机或者更复杂的网络结构
- priority:资源的优先级
- resource-requirement:资源的具体需求,现阶段指内存和cpu需求的数量
- number-of-containers:满足需求的Container的集合
-->
<resource-name, priority, resource-requirement, number-of-containers>

JobHistoryServer

作业历史服务,记录在yarn中调度的作业历史运行情况情况 , 通过mr-jobhistory-daemon.sh start historyserver命
令在集群中的数据节点机器上不需要做任何配置,单独使用命令启动直接启动即可, 启动成功后会出现
JobHistoryServer进程(使用jps命令查看,下面会有介绍) , 并且可以从19888端口进行查看日志详细信

执行mr-jobhistory-daemon.sh start historyserver命令启动jobhistoryserver。    

Timeline Server

用来写日志服务数据 , 一般来写与第三方结合的日志服务数据(比如spark等),从官网的介绍看,它是对
jobhistoryserver功能的有效补充,jobhistoryserver只能对mapreduce类型的作业信息进行记录,除了
jobhistoryserver能够进行对作业运行过程中信息进行记录之外还有更细粒度的信息记录,比如任务在哪个队列中
运行,运行任务时设置的用户是哪个用户。
根据官网的解释jobhistoryserver只能记录mapreduce应用程序的记录,timelineserver功能更强大,但不是替代
jobhistory两者是功能间的互补关系

三、 yarn应用运行原理

YARN 是如何工作的? YARN的基本理念是将JobTracker/TaskTracker 两大职能分割为以下几个实体:
1. 一个全局的资源管理ResourceManager
2. 每个应用程序一个ApplicationMaster
3. 每个从节点一个NodeManager
4. 每个应用程序一个运行在NodeManager上的Container
ResouceManager 和 NodeManager 组成了一个新的、通用的、用分布式管理应用程序的系统。
ResourceManager 对系统中的应用程序资源有终极仲裁的权限。ApplicationMaster 是一个特定于框架的实体,
它的责任是同ResourceManager 谈判资源 ,同时为NodeManager(s)执行和监控组件任务。RessourceManager
有一个调度器,根据不同的约束条件,例如队列容量、用户限制等,将资源进行分配给各类运行着的应用程序。调
度器执行调度功能是基于应用程序的资源申请。NodeManager 负责发布应用程序容器,监控资源的使用并向
ResourceManager进行汇报。每个ApplicationMaster都有职责从调度器那谈判得到适当的资源容器,追踪它们的
状态,并监控他们的进程。从系统的视图看,ApplicationMaster 作为一个普通的容器运行着

yarn应用提交过程

    Application在Yarn中的执行过程,整个执行过程可以总结为三步:
    1. 应用程序提交
    2. 启动应用的ApplicationMaster实例
    3. ApplicationMaster 实例管理应用程序的执行
    具体提交过程为:
    1. 客户端程序向 ResourceManager 提交应用并请求一个 ApplicationMaster 实例;
    2. ResourceManager 找到一个可以运行一个 Container 的 NodeManager,并在这个 Container 中启动
    ApplicationMaster 实例;
    3. ApplicationMaster 向 ResourceManager 进行注册,注册之后客户端就可以查询 ResourceManager 获得自
    己 ApplicationMaster 的详细信息,以后就可以和自己的 ApplicationMaster 直接交互了(这个时候,客户
    端主动和 ApplicationMaster 交流,应用先向 ApplicationMaster 发送一个满足自己需求的资源请求);
    4. 在平常的操作过程中,ApplicationMaster 根据 resource-request协议 向 ResourceManager 发送 resource-
    request请求;
    5. 当 Container 被成功分配后,ApplicationMaster 通过向 NodeManager 发送 container-launch-
    specification信息 来启动Container,container-launch-specification信息包含了能够让Container 和
    ApplicationMaster 交流所需要的资料;
    6. 应用程序的代码以 task 形式在启动的 Container 中运行,并把运行的进度、状态等信息通过 application-
    specific协议 发送给ApplicationMaster;
    7. 在应用程序运行期间,提交应用的客户端主动和 ApplicationMaster 交流获得应用的运行状态、进度更新等
    信息,交流协议也是 application-specific协议;
    8. 一旦应用程序执行完成并且所有相关工作也已经完成,ApplicationMaster 向 ResourceManager 取消注册然
    后关闭,用到所有的 Container 也归还给系统
    
精简版的: 
    步骤1:用户将应用程序提交到 ResourceManager 上; 
    步骤2:ResourceManager 为应用程序ApplicationMaster 申请资源,并与某个 NodeManager 通信启动第一个 Container,以启动ApplicationMaster; 
    步骤3:ApplicationMaster 与 ResourceManager 注册进行通信,为内部要执行的任务申请资源,一旦得到资源后,将于 NodeManager 通信,以启动对应的 Task; 
    步骤4:所有任务运行完成后,ApplicationMaster 向 ResourceManager 注销,整个应用程序运行结束。

mapreduce on yarn
    
    MapReduce基于yarn的工作原理: 我们通过提交jar包,进行MapReduce处理,那么整个运行过程分为五个环
    节: 1、向client端提交MapReduce job. 2、随后yarn的ResourceManager进行资源的分配. 3、由
    NodeManager进行加载与监控containers. 4、通过applicationMaster与ResourceManager进行资源的申请
    及状态的交互,由NodeManagers进行MapReduce运行时job的管理. 5、通过hdfs进行job配置文件、jar包的各节
    点分发。

Job 初始化过程 
    1、当resourceManager收到了submitApplication()方法的调用通知后,scheduler开始分配
    container,随之ResouceManager发送applicationMaster进程,告知每个nodeManager管理器。 
    2、由applicationMaster决定如何运行tasks,如果job数据量比较小,applicationMaster便选择将tasks运行在一个JVM
    中。那么如何判别这个job是大是小呢?当一个job的mappers数量小于10个,只有一个reducer或者读取的文件大
    小要小于一个HDFS block时,(可通过修改配置项
    mapreduce.job.ubertask.maxmaps,mapreduce.job.ubertask.maxreduces以及
    mapreduce.job.ubertask.maxbytes 进行调整) 3、在运行tasks之前,applicationMaster将会调用setupJob()
    方法,随之创建output的输出路径(这就能够解释,不管你的mapreduce一开始是否报错,输出路径都会创建)
    
    
Task 任务分配 
    1、接下来applicationMaster向ResourceManager请求containers用于执行map与reduce的
    tasks(step 8),这里map task的优先级要高于reduce task,当所有的map tasks结束后,随之进行sort(这里是
    shuffle过程后面再说),最后进行reduce task的开始。(这里有一点,当map tasks执行了百分之5%的时候,将会请
    求reduce,具体下面再总结) 
    2、运行tasks的是需要消耗内存与CPU资源的,默认情况下,map和reduce的
    task资源分配为1024MB与一个核,(可修改运行的最小与最大参数配
    置,mapreduce.map.memory.mb,mapreduce.reduce.memory.mb,mapreduce.map.cpu.vcores,mapreduce.re
    duce.reduce.cpu.vcores.)
    
Task 任务执行 
    1、这时一个task已经被ResourceManager分配到一个container
    中,由applicationMaster告知nodemanager启动container,这个task将会被一个主函数为YarnChild的java
    application运行,但在运行task之前,首先定位task需要的jar包、配置文件以及加载在缓存中的文件。 
    2、YarnChild运行于一个专属的JVM中,所以任何一个map或reduce任务出现问题,都不会影响整个nodemanager的
    crash或者hang。 
    3、每个task都可以在相同的JVM task中完成,随之将完成的处理数据写入临时文件中。
    Mapreduce数据流 
    
运行进度与状态更新 
    1、MapReduce是一个较长运行时间的批处理过程,可以是一小时、
    几小时甚至几天,那么Job的运行状态监控就非常重要。每个job以及每个task都有一个包含
    job(running,successfully completed,failed)的状态,以及value的计数器,状态信息及描述信息(描述信息一
    般都是在代码中加的打印信息),那么,这些信息是如何与客户端进行通信的呢? 
    2、当一个task开始执行,
    它将会保持运行记录,记录task完成的比例,对于map的任务,将会记录其运行的百分比,对于reduce来说可能复
    杂点,但系统依旧会估计reduce的完成比例。当一个map或reduce任务执行时,子进程会持续每三秒钟与
    applicationMaster进行交互。 Job 完成
    
yarn应用生命周期

    RM: Resource Manager
    AM: Application Master
    NM: Node Manager
    1. Client向RM提交应用,包括AM程序及启动AM的命令。
    2. RM为AM分配第一个容器,并与对应的NM通信,令其在容器上启动应用的AM。
    3. AM启动时向RM注册,允许Client向RM获取AM信息然后直接和A
    通信。
    4. AM通过资源请求协议,为应用协商容器资源。
    5. 如容器分配成功,AM要求NM在容器中启动应用,应用启动后可以和AM独立通信。
    6. 应用程序在容器中执行,并向AM汇报。
    7. 在应用执行期间,Client和AM通信获取应用状态。
    8. 应用执行完成,AM向RM注销并关闭,释放资源。
    申请资源->启动appMaster->申请运行任务的container->分发Task->运行Task->Task结束->回收
    container

四、 如何使用yarn

配置文件
    
    <!-- $HADOOP_HOME/etc/hadoop/mapred-site.xml -->
    <configuration>
    <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
    </property>
    </configuration>
    
    <!-- $HADOOP_HOME/etc/hadoop/yarn-site.xml -->
    <configuration>
    <property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
    </property>
    </configuration>
    
yarn启动停止

    启动 ResourceManager 和 NodeManager 
        #主节点运行命令
        $HADOOP_HOME/sbin/start-yarn.sh
    停止 RM 和 NM
        #主节点运行命令
        $HADOOP_HOME/sbin/stop-yarn.sh
    若RM没有启动起来,可以单独启动
        #若RM没有启动,在主节点运行命令
        $HADOOP_HOME/sbin/yarn-daemon.sh start resouremanager
        #相反,可单独关闭
        $HADOOP_HOME/sbin/yarn-daemon.sh stop resouremanager
    若NM没有启动起来,可以单独启动
        #若NM没有启动,在相应节点运行命令
        $HADOOP_HOME/sbin/yarn-daemon.sh start nodemanager
        #相反,可单独关闭
        $HADOOP_HOME/sbin/yarn-daemon.sh stop nodemanager
    
yarn常用命令

 yarn application命令

    #1.查看正在运行的任务
    yarn application -list
    
    #3.查看节点列表
    yarn node -list

    #4.查看节点状况 TODO
    yarn node -status node3:40652
    
    #5.查看yarn依赖jar的环境变量
    yarn classpath

五、yarn调度器

试想一下,你现在所在的公司有一个hadoop的集群。但是A项目组经常做一些定时的BI报表,B项目组则经常使用
一些软件做一些临时需求。那么他们肯定会遇到同时提交任务的场景,这个时候到底如何分配资源满足这两个任务
呢?是先执行A的任务,再执行B的任务,还是同时跑两个?
如果你存在上述的困惑,可以多了解一些yarn的资源调度器。
在Yarn框架中,调度器是一块很重要的内容。有了合适的调度规则,就可以保证多个应用可以在同一时间有条不紊
的工作。最原始的调度规则就是FIFO,即按照用户提交任务的时间来决定哪个任务先执行,先提交的先执行。但是
这样很可能一个大任务独占资源,其他的资源需要不断的等待。也可能一堆小任务占用资源,大任务一直无法得到
适当的资源,造成饥饿。所以FIFO虽然很简单,但是并不能满足我们的需求。
理想情况下,yarn应用发出的资源请求应该立刻给予满足。然而现实中的资源有限,在一个繁忙的集群上,一个应
用经常需要等待才能得到所需的资源。yarn调度器的工作就是根据既定的策略为应用分配资源。调度通常是一个难
题,并且没有一个所谓的“最好”的策略,这也是为什么yarn提供了多重调度器和可配置策略供我们选择的原因。
yarn分为一级调度管理和二级调度管理 一级调度管理(更近底层,更接近于操作资源, 更偏向于应用层和底层结合) 计
算资源管理(cpu,内存等,计算复杂消耗的cpu多) App生命周期管理 二级调度管理(自己代码的算法等, 更偏向于应用
层) App内部的计算模型管理 多样化的计算模型

在Yarn中有三种调度器可以选择:FIFO(first in first out) Scheduler ,Capacity Scheduler,FairS cheduler

FIFO Scheduler
    FIFO Scheduler把应用按提交的顺序排成一个队列,这是一个先进先出队列,在进行资源分配的时候,先给队列中
    最头上的应用进行分配资源,待最头上的应用需求满足后再给下一个分配,以此类推。
    FIFO Scheduler是最简单也是最容易理解的调度器,也不需要任何配置,但它并不适用于共享集群。大的应用可能
    会占用所有集群资源,这就导致其它应用被阻塞。在共享集群中,更适合采用Capacity Scheduler或Fair
    Scheduler,这两个调度器都允许大任务和小任务在提交的同时获得一定的系统资源。
    
Capacity Scheduler
    而对于Capacity调度器,有一个专门的队列用来运行小任务,但是为小任务专门设置一个队列会预先占用一定的集
    群资源,这就导致大任务的执行时间会落后于使用FIFO调度器时的时间。
    如何配置容量调度器
    队列层级结构如下:
    root
    ├── prod
    └── dev
        ├── spark
        └── hdp
    
    将 中 的 对 应 配 ? ? 件 备 ? ? 其 ? 目 录 , 在 目 录
    HADOOP_HOME/etc/hadoop/中建立一个新的capacity-scheduler.xml;内容如下
    
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <property>
    <name>yarn.scheduler.capacity.root.queues</name>
    <value>prod,dev</value>
    </property>
    <property>
    <name>yarn.scheduler.capacity.root.dev.queues</name>
    <value>hdp,spark</value>
    </property>
    <property>
    <name>yarn.scheduler.capacity.root.prod.capacity</name>
    <value>40</value>
    </property>
    <property>
    <name>yarn.scheduler.capacity.root.dev.capacity</name>
    <value>60</value>
    </property>
    <property>
    <name>yarn.scheduler.capacity.root.dev.maximum-capacity</name>
    <value>75</value>
    </property>
    <property>
    <name>yarn.scheduler.capacity.root.dev.hdp.capacity</name>
    <value>50</value>
    </property>
    <property>
    <name>yarn.scheduler.capacity.root.dev.spark.capacity</name>
    <value>50</value>
    </property>
    </configuration>
    
程序打包,提交集群运行
    [bruce@node-01 Desktop]$ hadoop jar com.kaikeba.hadoop-1.0-SNAPSHOT.jar
    com.test.hadoop.scheduler.WordCountMain /sogou.500w.utf8 /0717scheduler02
    
Fair Scheduler
    在Fair调度器中,我们不需要预先占用一定的系统资源,Fair调度器会为所有运行的job动态的调整系统资源。如上
    图所示,当第一个大job提交时,只有这一个job在运行,此时它获得了所有集群资源;当第二个小任务提交后,
    Fair调度器会分配一半资源给这个小任务,让这两个任务公平的共享集群资源。
    需要注意的是,在下图Fair调度器中,从第二个任务提交到获得资源会有一定的延迟,因为它需要等待第一个任务
    释放占用的Container。小任务执行完成之后也会释放自己占用的资源,大任务又获得了全部的系统资源。最终的
    效果就是Fair调度器即得到了高的资源利用率又能保证小任务及时完成.

六、yarn应用状态

我们在yarn 的web ui上能够看到yarn 应用程序分为如下几个状态:
    NEW -----新建状态
    NEW_SAVING-----新建保存状态
    SUBMITTED-----提交状态
    ACCEPTED-----接受状态
    RUNNING-----运行状态
    FINISHED-----完成状态
    FAILED-----失败状态
    KILLED-----杀掉状态

七、yarn调优

关于Yarn内存分配与管理,主要涉及到了ResourceManage、ApplicationMatser、NodeManager这几个概念,
相关的优化也要紧紧围绕着这几方面来开展。这里还有一个Container的概念,现在可以先把它理解为运行
map/reduce task的容器,后面有详细介绍。

RM的内存资源配置, 配置的是资源调度相关
    
    RM1:yarn.scheduler.minimum-allocation-mb 分配给AM单个容器可申请的最小内存 RM2:
    yarn.scheduler.maximum-allocation-mb 分配给AM单个容器可申请的最大内存 注:
    最小值可以计算一个节点最大Container数量 一旦设置,不可动态改变

NM的内存资源配置,配置的是硬件资源相关
    NM1:yarn.nodemanager.resource.memory-mb 节点最大可用内存 NM2:yarn.nodemanager.vmem-pmem-
    ratio 虚拟内存率,默认2.1 注:
    RM1、RM2的值均不能大于NM1的值 NM1可以计算节点最大最大Container数量,max(Container)=NM1/RM1 一
    旦设置,不可动态改变
    
AM内存配置相关参数,配置的是任务相关
    AM1:mapreduce.map.memory.mb 分配给map Container的内存大小 AM2:mapreduce.reduce.memory.mb
    分配给reduce Container的内存大小
    这两个值应该在RM1和RM2这两个值之间 AM2的值最好为AM1的两倍 这两个值可以在启动时改变
    AM3:mapreduce.map.java.opts 运行map任务的jvm参数,如-Xmx,-Xms等选项 AM4:
    mapreduce.reduce.java.opts 运行reduce任务的jvm参数,如-Xmx,-Xms等选项 注:
    这两个值应该在AM1和AM2之间

如上图所示,先看最下面褐色部分, AM参数mapreduce.map.memory.mb=1536MB,表示AM要为map
Container申请1536MB资源,但RM实际分配的内存却是2048MB,因为yarn.scheduler.mininum-allocation-
mb=1024MB,这定义了RM最小要分配1024MB,1536MB超过了这个值,所以实际分配给AM的值为2048MB(这
涉及到了规整化因子,关于规整化因子,在本文最后有介绍)。 AM参数mapreduce.map.java.opts=-Xmx
1024m,表示运行map任务的jvm内存为1024MB,因为map任务要运行在Container里面,所以这个参数的值略微
小于mapreduce.map.memory.mb=1536MB这个值。 NM参数yarn.nodemanager.vmem-pmem-radio=2.1,这
表示NodeManager可以分配给map/reduce Container 2.1倍的虚拟内存,安照上面的配置,实际分配给map
Container容器的虚拟内存大小为2048*2.1=3225.6MB,若实际用到的内存超过这个值,NM就会kill掉这个map
Container,任务执行过程就会出现异常。 AM参数mapreduce.reduce.memory.mb=3072MB,表示分配给reduce
Container的容器大小为3072MB,而map Container的大小分配的是1536MB,从这也看出,reduce Container容
器的大小最好是map Container大小的两倍。 NM参数yarn.nodemanager.resource.mem.mb=24576MB,这个值
表示节点分配给NodeManager的可用内存,也就是节点用来执行yarn任务的内存大小。这个值要根据实际服务器
内存大小来配置,比如我们hadoop集群机器内存是128GB,我们可以分配其中的80%给yarn,也就是102GB。 上
图中RM的两个参数分别1024MB和8192MB,分别表示分配给AM map/reduce Container的最大值和最小值。

关于Container
    
    (1)Container是YARN中资源的抽象,它封装了某个节点上一定量的资源(CPU和内存两类资源)。它跟Linux
    Container没有任何关系,仅仅是YARN提出的一个概念(从实现上看,可看做一个可序列化/反序列化的Java
    类)。 
    (2)Container由ApplicationMaster向ResourceManager申请的,由ResouceManager中的资源调度器
    异步分配给ApplicationMaster; 
    (3)Container的运行是由ApplicationMaster向资源所在的NodeManager发起
    的,Container运行时需提供内部执行的任务命令(可以使任何命令,比如java、Python、C++进程启动命令均
    可)以及该命令执行所需的环境变量和外部资源(比如词典文件、可执行文件、jar包等)。 另外,一个应用程序
    所需的Container分为两大类,如下: (1) 运行ApplicationMaster的Container:这是由ResourceManager(向
    内部的资源调度器)申请和启动的,用户提交应用程序时,可指定唯一的ApplicationMaster所需的资源; (2)
    运行各类任务的Container:这是由ApplicationMaster向ResourceManager申请的,并由ApplicationMaster与
    NodeManager通信以启动之。 以上两类Container可能在任意节点上,它们的位置通常而言是随机的,即
    ApplicationMaster可能与它管理的任务运行在一个节点上。 Container是YARN中最重要的概念之一,懂得该概念
    对于理解YARN的资源模型至关重要,望大家好好理解。 注意:如下图,map/reduce task是运行在Container之中
    的,所以上面提到的mapreduce.map(reduce).memory.mb大小都大于mapreduce.map(reduce).java.opts值的
    大小。