1. Yarn的架构和原理

1.1 Yarn的基本介绍和产生背景

YARN是Hadoop2引入的通用的资源管理和任务调度的平台,可以在YARN上运行MapReduce、Tez、Spark等多种计算框架,只要计算框架实现了YARN所定义的接口,都可以运行在这套通用的Hadoop资源管理和任务调度平台上。
Hadoop 1.0是由HDFS和MapReduce V1组成的,YARN出现之前是MapReduce V1来负责资源管理和任务调度,MapReduce V1由JobTracker和TaskTracker两部分组成。
MapReduce V1有如下缺点:

  1. 扩展性差:在MapReduce V1中,JobTracker同时负责资源管理和任务调度,而JobTracker只有一个节点,所以JobTracker成为了制约系统性能的一个瓶颈,制约了Hadoop平台的扩展性。
  2. 可靠性低:MapReduce V1中JobTracker存在单点故障问题,所以可靠性低。
  3. 资源利用率低:MapReduce V1采用了基于槽位的资源分配模型,槽位是一种粗粒度的资源划分单位。
  • 一是通常情况下为一个job分配的槽位不会被全部利用。
  • 二是一个MapReduce任务的Map阶段和Reduce阶段会划分了固定的槽位,并且不可以共用,很多时候一种类型的槽位资源很紧张而另外一种类型的槽位很空闲,导致资源利用率低。
  1. 不支持多种计算框架MapReduce V1这种资源管理和任务调度方式只适合MapReduce这种计算框架,而MapReduce这种离线计算框架很多时候不能满足应用需求。

yarn的优点:

  1. 支持多种计算框架YARN是通用的资源管理和任务调度平台,只要实现了YARN的接口的计算框架都可以运行在YARN上。
  2. 资源利用率高多种计算框架可以共用一套集群资源,让资源充分利用起来,提高了利用率。
  3. 运维成本低避免一个框架一个集群的模式,YARN降低了集群的运维成本。
  4. 数据可共享共享集群模式可以让多种框架共享数据和硬件资源,减少数据移动带来的成本。

    1.2 hadoop 1.0 和 hadoop 2.0 的区别

  5. 组成部分

Hadoop1.0由HDFS和MapReduce组成,Hadoop2.0由HDFS和YARN组成。

  1. HDFS可扩展性

Hadoop1.0中的HDFS只有一个NameNode,制约着集群文件个数的增长,Hadoop2.0增加了HDFS联盟的架构,可以将NameNode所管理的NameSpace水平划分,增加了HDFS的可扩展性。

  1. HDFS的可靠性

Hadoop1.0中的HDFS只有一个NameNode,存在着单点故障的问题,Hadoop2.0提供了HA的架构,可以实现NameNode的热备份和热故障转移,提高了HDFS的可靠性。

  1. 可支持的计算框架

Hadoop1.0中只支持MapReduce一种计算框架,Hadoop2.0因为引入的YARN这个通用的资源管理与任务调度平台,可以支持很多计算框架了。

  1. 资源管理和任务调度

Hadoop1.0中资源管理和任务调度依赖于MapReduce中的JobTracker,JobTracker工作很繁重,很多时候会制约集群的性能。Hadoop2.0中将资源管理任务分给了YARN的ResourceManage,将任务调度分给了YARN的ApplicationMaster。

1.3 Yarn 集群的架构和工作原理

YARN的基本设计思想是将MapReduce V1中的JobTracker拆分为两个独立的服务:ResourceManager和ApplicationMaster。ResourceManager负责整个系统的资源管理和分配,ApplicationMaster负责单个应用程序的的管理。
Hadoop之Yarn详解 - 图1

  1. ResourceManager

RM是一个全局的资源管理器,负责整个系统的资源管理和分配,它主要由两个部分组成:调度器(Scheduler)和应用程序管理器(Application Manager)
调度器:根据容量、队列等限制条件,将系统中的资源分配给正在运行的应用程序,在保证容量、公平性和服务等级的前提下,优化集群资源利用率,让所有的资源都被充分利用 。
应用程序管理器:负责管理整个系统中的所有的应用程序,包括应用程序的提交、与调度器协商资源以启动ApplicationMaster、监控ApplicationMaster运行状态并在失败时重启它。

  1. ApplicationMaster

用户提交的一个应用程序会对应于一个ApplicationMaster,它的主要功能有:

  • 与RM调度器协商以获得资源,资源以Container表示。
  • 将得到的任务进一步分配给内部的任务。
  • 与NM通信以启动/停止任务。
  • 监控所有的内部任务状态,并在任务运行失败的时候重新为任务申请资源以重启任务。
  1. nodeManager

NodeManager是每个节点上的资源和任务管理器,一方面,它会定期地向RM汇报本节点上的资源使用情况和各个Container的运行状态;另一方面,他接收并处理来自AM的Container启动和停止请求。

  1. container

Container是YARN中的资源抽象,封装了各种资源。一个应用程序会分配一个Container,这个应用程序只能使用这个Container中描述的资源。
不同于MapReduceV1中槽位slot的资源封装,Container是一个动态资源的划分单位,更能充分利用资源。

1.4 Yarn 的任务提交流程

Hadoop之Yarn详解 - 图2
当jobclient向YARN提交一个应用程序后,YARN将分两个阶段运行这个应用程序:一是启动ApplicationMaster第二个阶段是由ApplicationMaster创建应用程序,为它申请资源,监控运行直到结束。
具体步骤如下:

  1. 用户向YARN提交一个应用程序,并指定ApplicationMaster程序、启动ApplicationMaster的命令、用户程序。
  2. RM为这个应用程序分配第一个Container,并与之对应的NM通讯,要求它在这个Container中启动应用程序ApplicationMaster。
  3. ApplicationMaster向RM注册,然后拆分为内部各个子任务,为各个内部任务申请资源,并监控这些任务的运行,直到结束。
  4. AM采用轮询的方式向RM申请和领取资源。
  5. RM为AM分配资源,以Container形式返回
  6. AM申请到资源后,便与之对应的NM通讯,要求NM启动任务。
  7. NodeManager为任务设置好运行环境,将任务启动命令写到一个脚本中,并通过运行这个脚本启动任务
  8. 各个任务向AM汇报自己的状态和进度,以便当任务失败时可以重启任务。
  9. 应用程序完成后,ApplicationMaster向ResourceManager注销并关闭自己

    1.5 Yarn基础架构

    image.png

    2. RM和NM的功能介绍

    2.1 ResourceManager基本介绍

    ResourceManager负责集群中所有资源的统一管理和分配,它接收来自各个NodeManager的资源汇报信息,并把这些信息按照一定的策略分配给各个ApplicationMaster。

    2.1.1 RM的职能

  10. 与客户端交互,处理客户端的请求。

  11. 启动和管理AM,并在它运行失败时候重新启动它。
  12. 管理NM,接收来自于NM的资源汇报信息,并向NM下达管理指令。
  13. 资源管理和调度,接收来自于AM的资源请求,并为它分配资源。

    2.1.2 RM 的内部结构

    Hadoop之Yarn详解 - 图4
    用户交互模块:

  14. clientRMService : 为普通用户服务,处理请求,如:提交应用程序、终止程序、获取程序状态。

  15. adminService : 给管理员提供的服务。普通用户交互模块是ClientRMService,管理员交互模块是AdminService,之所以要将两个模块分开,用不同的通信通道发送给ResourceManager,是因为要避免普通用户的请求过多导致管理员请求被阻塞。
  16. WebApp : 更友好的展示集群资源和程序运行状态。

NM管理模块:

  1. NMLivelinessMonitor : 监控NM是否活着,如果指定时间内未收到心跳,就从集群中移除。RM会通过心跳告诉AM某个NM上的Container失效,如果Am判断需要重新执行,则AM重新向RM申请资源。
  2. NodesListManager : 维护inlude(正常)和exlude(异常)的NM节点列表。默认情况下,两个列表都为空,可以由管理员添加节点。exlude列表里的NM不允许与RM进行通信。
  3. ResourceTrackerService : 处理来自NM的请求,包括注册和心跳。注册是NM启动时的操作,包括节点ID和可用资源上线等。心跳包括各个Container运行状态,运行Application列表、节点健康状态。

AM管理模块:

  1. AMLivelinessMonitor:监控AM是否还活着,如果指定时间内没有接受到心跳,则将正在运行的Container置为失败状态,而AM会被重新分配到另一个节点上。
  2. ApplicationMasterLauncher: 要求某一个NM启动ApplicationMaster,它处理创建AM的请求和kill AM的请求。
  3. ApplicationMasterService:处理来自AM的请求,包括注册、心跳、清理。注册是在AM启动时发送给ApplicationMasterService的;心跳是周期性的,包括请求资源的类型、待释放的Container列表;清理是程序结束后发送给RM,以回收资源清理内存空间。

Application管理模块:

  1. ApplicationACLLsManager : 管理应用程序的访问权限,分为查看权限和修改权限。
  2. RMAppManager : 管理应用程序的启动和关闭。
  3. ContainerAllocationExpirer : RM分配Container给AM后,不允许AM长时间不对Container使用,因为会降低集群的利用率,如果超时(时间可以设置)还没有在NM上启动Container,RM就强制回收Container。

状态机管理模块:

  1. RMApp : RMApp维护一个应用程序的的整个运行周期,一个应用程序可能有多个实例,RMApp维护的是所有实例的。
  2. RMAppAttempt : RMAppAttempt维护一个应用程序实例的一次尝试的整个生命周期。
  3. RMContainer : RMContainer维护一个Container的整个运行周期(可能和任务的周期不一致)。
  4. RMNode : RMNode维护一个NodeManager的生命周期,包括启动到运行结束的整个过程。

安全模块:

  • RM自带了全面的权限管理机制。主要由ClientToAMSecretManager、ContainerTokenSecretManager、ApplicationTokenSecretManager等模块组成。

资源分配模块:

  • ResourceScheduler:ResourceScheduler是资源调度器,他按照一定的约束条件将资源分配给各个应用程序。RM自带了一个批处理资源调度器(FIFO)和两个多用户调度器Fair Scheduler 和Capacity Scheduler

    2.1.3 启动ApplicationMaster

    Hadoop之Yarn详解 - 图5
  1. 客户端提交一个任务给RM,ClientRMService负责处理客户端请求。
  2. ClentRMService通知RMAppManager。
  3. RMAppManager为应用程序创建一个RMApp对象来维护任务的状态。
  4. RMApp启动任务,创建RMAppAttempt对象。
  5. RMAppAttempt进行一些初始化工作,然后通知ResourceScheduler申请资源。
  6. ResourceScheduler为任务分配资源后,创建一个RMContainer维护Container状态。
  7. 并通知RMAppAttempt,已经分配资源。
  8. RMAppAttempt通知ApplicationMasterLauncher在资源上启动AM。
  9. 在NodeManager的已分配资源上启动AM。
  10. AM启动后向ApplicationMasterService注册。

    2.1.4 申请和分配container

    AM向RM请求资源和RM为AM分配资源是两个阶段的循环过程:
  • 阶段一:AM请求资源请求并领取资源的过程,这个过程是AM发送请求、RM记录请求。
  • 阶段二:NM向RM汇报各个Container运行状态,如果RM发现它上面有空闲的资源就分配给等待的AM。

具体过程如下:
阶段一:

  1. AM通过RPC函数向RM发送资源需求信息,包括新的资源需求描述、待释放的Container列表、请求加入黑名单的节点列表、请求移除黑名单的节点列表等
  2. RM的ApplicationMasterService负责处理AM的请求。一旦收到请求,就通知RMAppAttempt,更新应用程序执行进度,在AMLivenessMonitor中记录更新时间。
  3. ApplicationMasterService调用ResourceScheduler,将AM的资源需求汇报给ResourceScheduler。
  4. ResouceScheduler首先读取待释放的Container列表,通知RMContainer更改状态,杀死要释放的Container,然后将新的资源需求记录,如果资源足够就记录已经分配好资源。

阶段二:

  1. NM通过RPC向RM汇报各自的各个Container的运行情况
  2. RM的ResourceTrackerService负责处理来自NM的汇报,收到汇报后,就通知RMNode更改Container状态,并通知ResourceScheduler。
  3. ResourceScheduler收到通知后,如果有可分配的空闲资源,就将资源分配给等待资源的AM,等待AM下次心跳将资源领取走。

Hadoop之Yarn详解 - 图6

2.1.5 杀死 application

杀死Application流程:Kill Job通常是客户端发起的,RM的ClientRMService负责处理请求,接收到请求后,先检查权限,确保用户有权限Kill Job,然后通知维护这个Application的RMApp对象,根据Application当前状态调用相应的函数来处理。
这个时候分为两种情况:Application没有在运行、Application正在运行。

  1. Application没有在运行

向已经运行过的NodeManger节点对应的状态维护对象RMNode发送通知,进行清理;向RMAppManager发送通知,将Application设置为已完成状态。

  1. Application正在运行

如果正在运行,也首先像情况一处理一遍,回收运行过的NodeManager资源,将Application设置为已完成。另外RMApp还要通知维护任务状态的RMAppAttempt对象,将已经申请和占用的资源回收,但是真正的回收是由资源调度器ResourceScheduler异步完成的。
异步完成的步骤是先由ApplicationMasterLauncher杀死AM,并回收它占用的资源,再由各个已经启动的RMContainer杀死Container并回收资源。

2.1.6 Container超时

YARN里有两种Container:运行AM的Container运行普通任务的Container

  1. RM为要启动的AM分配Container后,会监控Container的状态,如果指定时间内AM还没有在Container上启动的话,Container就会被回收,AM Container超时会导致Application执行失败。
  2. 普通Container超时会进行资源回收,但是YARN不会自动在其他资源上重试,而是通知AM,由AM决定是否重试。

    2.1.7 安全管理

    Hadoop的安全管理是为了更好地让多用户在共享Hadoop集群环境下安全高效地使用集群资源。系统安全机制由认证和授权两大部分构成,Hadoop2.0中的认证机制采用Kerberos和Token两种方案,而授权则是通过引入访问控制表(Access Control List,ACL)实现的。

  3. 术语

Kerberos是一种基于第三方服务的认证协议,非常安全。特点是用户只需要输入一次身份验证信息就可以凭借此验证获得的票据访问多个服务。
Token是一种基于共享密钥的双方身份认证机制。
Principal是指集群中被认证或授权的主体,主要包括用户、Hadoop服务、Container、Application、Localizer、Shuffle Data等。

  1. Hadoop认证机制

Hadoop同时采用了Kerberos和Token两种技术,服务和服务之间的认证采用了Kerberos,用户和NameNode及用户和ResourceManager首次通讯也采用Kerberos认证,用户和服务之间一旦建立连接后,用户就可以从服务端获取一个Token,之后就可以使用Token认证通讯了。因为Token认证要比Kerberos要高效。
Hadoop里Kerberos认证默认是关闭的,可以通过参数hadoop.security.authentication设置为kerberos,这个配置模式是simple。

  1. Hadoop授权机制

Hadoop授权是通过访问控制列表(ACL)实现的,Hadoop的访问控制机制与UNIX的POSIX风格的访问控制机制是一致的,将权限授予对象分为:用户、同组用户、其他用户。默认情况下,Hadoop公用UNIX/Linux下的用户和用户组。

  • 队列访问控制列表
  • 应用程序访问控制列表
  • 服务访问控制列表

    2.2 NodeManager功能介绍

    NM是单个节点上的代理,功能包括与ResourceManager保持通讯、管理Container的生命周期、监控Container的资源使用、追踪节点健康状态、管理日志。

    2.2.1 基本内部构造

    Hadoop之Yarn详解 - 图7
    各模块说明:
模块 说明
NodeStatusUpdater NodeStatusUpdater是NM和RM通讯的唯一通道。NM启动时,该组件负责向RM注册、汇报节点总的可用资源。该组件周期性地汇报各个Container的状态,接收RM返回的待清理的Container列表等。
ContainerManager ContainerManager是NM最核心的模块。
RPC Server 是AM和NM通讯的唯一通道,接收AM请求,启动或者停止Container。
ResourceLocalizationService 负责Container所需资源的本地化,下载文件资源,尽量分摊到各个磁盘。
ContainersLauncher 维护一个线程池并行操作Container。
AuxServices NM附属服务。
ContainersMonitor ContainersMonitor负责监控Container的资源使用量。
LogHandler 用户可以通过LogHandler控制Container日志保存方式。
ContainerEventDispatcher Container事件调度器,负责将ContainerEvent类型的事件调度给对应的Container的状态机。
ApplicationEventDispatcher Application事件调度器,负责将ApplicationEvent类型的事件调度给对应。
ContainerExecutor ContainerExecutor可与底层操作系统交互,安全存放Container需要的文件和目录,启动和清除Container对应的进程。
NodeHealthCheckerServiceNodeHealthCheckerService 通过周期性运行一个脚本和写磁盘检测节点的健康状况,并通知RM。NodeHealthScriptRunner:运行脚本检测LocalDirsHandlerService:写磁盘文件检测。
DeletionService NM将文件删除功能化,DeletionService异步删除文件,避免同步删除文件带来的性能开销。
Security 安全模块分为两部分:ApplicationACLManager确保访问NM的用户是合法的。ContainerTokenSecreManager确保用户请求的资源被RM授权过。
WebServer Web UI向用户展示。

2.2.2 状态机管理

NodeManager维护着三类状态机,分别是Application、Container、LocalizedResource。

  1. Application状态机:RM上有一个整个集群上Application信息列表,而一个NM上也有一个处在它自己节点的Application的信息列表,NodeManager上的Application状态机维护着NodeManager上Application的状态。这有利于对一个NM节点上的同一个Application所有的Container进行统一管理。
  2. Container状态机:Container状态机维护NodeManager上所有Container的生命周期。
  3. LocalizedResource状态机:LocalizedResource状态是NodeManager上用于维护一个资源生命周期的数据结构。资源包括文件、JAR包等。

    2.2.3 container生命周期的管理

    NodeManager中的ContainerManager负责接收AM发来的请求以启动Container,Container的启动过程分三个阶段:资源本地化、启动并运行Container、资源清理。

  4. 资源本地化

资源本地化主要是进行分布是缓存工作,分为应用程序初始化和Container本地化。

  1. 运行Container

Container运行是由ContainerLauncher服务完成启动后,调用ContainerExecutor来进行的。主要流程为:将待运行的Container所需要的环境变量和运行命令写到Shell脚本launch_container.sh中,并将启动该脚本的命令写入default_container_executor.sh中,然后通过运行该脚本启动container。

  1. 资源清理

container清理是资源本地化的逆过程,是指当container运行完成后,NodeManager来回收资源。

3. Yarn的ApplicationMaster介绍

ApplicationMaster实际上是特定计算框架的一个实例,每种计算框架都有自己独特的ApplicationMaster,负责与ResourceManager协商资源,并和NodeManager协同来执行和监控Container。MapReduce只是可以运行在YARN上一种计算框架。

3.1 ApplicationMaster的职能

Application启动后,将负责以下任务:

  1. 初始化向ResourceManager报告自己的活跃信息的进程 (注册)。
  2. 计算应用程序的的资源需求。
  3. 将需求转换为YARN调度器可以理解的ResourceRequest。
  4. 与调度器协商申请资源。
  5. 与NodeManager协同合作使用分配的Container。
  6. 跟踪正在运行的Container状态,监控它的运行。
  7. 对Container或者节点失败的情况进行处理,在必要的情况下重新申请资源。

    3.2 报告活跃

  8. 注册

ApplicationMaster执行的第一个操作就是向ResourceManager注册,注册时AM告诉RM它的IPC的地址和网页的URL。注册后,RM返回AM可以使用的信息,包括:YARN接受的资源的大小范围、应用程序的ACL信息。
IPC地址:是面向客户端的服务地址。
网页URL:是AM的一个Web服务的地址,客户端可以通过Http获取应用程序的状态和信息。

  1. 心跳注册成功后,AM需要周期性地发送心跳到RM确认他还活着。参数yarn.am.liveness-monitor.expiry配置AM心跳最大周期,如果RM发现超过这个时间还没有收到AM的心跳,那么就判断AM已经死掉。

    3.3 资源需求

    AM所需要的资源分为静态资源和动态资源。

  2. 静态资源

在任务提交时就能确定,并且在AM运行时不再变化的资源是静态资源,比如MapReduce程序中的Map的数量。

  1. 动态资源

AM在运行时确定要请求数量的资源是动态资源。

3.4 调度任务

当AM的资源请求数量达到一定数量或者到了心跳时,AM才会发送心跳到RM,请求资源,心跳是以ResourceRequest形式发送的,包括的信息有:resourceAsks、ContainerID、containersToBeReleased。
RM响应的信息包括:新分配的Container列表、已经完成了的Container状态、集群可用的资源上限。

3.5 启动container

  1. AM从RM那里得到了Container后就可以启动Container了。
  2. AM首先构造ContainerLaunchContext对象,包括分配资源的大小、安全令牌、启动Container执行的命令、进程环境、必要的文件等。
  3. AM与NM通讯,发送StartContainerRequest请求,逐一或者批量启动Container。
  4. NM通过StartContainerResponse回应请求,包括:成功启动的Container列表、失败的Container信信息等。
  5. 整个过程中,AM没有跟RM进行通信。
  6. AM也可以发送StopContainerRequest请求来停止Container。

    3.6 完成的container

    当Container执行结束时,由RM通知AM Container的状态,AM解释Container状态并决定如何继续操作。所以YARN平台只是负责为计算框架提供Container信息。

    3.7 AM的失败和恢复

    当AM失效后,YARN只负责重新启动一个AM,任务恢复到失效前的状态是由AM自己完成的。AM为了能实现恢复任务的目标,可以采用以下方案:将任务的状态持久化到外部存储中。比如:MapReduce框架的ApplicationMaster会将已完成的任务持久化,失效后的恢复时可以将已完成的任务恢复,重新运行未完成的任务。

    3.8 ApplicationMaster启动过程

    image.png

    4. Yarn的资源调度

  7. 资源调度器的职能

资源调度器是YARN最核心的组件之一,是一个插拔式的服务组件,负责整个集群资源的管理和分配。YARN提供了三种可用的资源调度器:FIFO(先进先出)、Capacity Scheduler(容量调度器)、Fair Scheduler(公平调度器)

  1. 资源调度器的分类

不同的任务类型对资源有着不同的负责质量要求,有的任务对时间要求不是很高(如Hive),有的任务要求及时返还结果(如HBase),有的任务是CPU密集型的(如过滤、统计类作业),有的是I/O密集型的(如数据挖掘、机器学习),所以简单的一种调度器并不能完全符合所有的任务类型。
有两种调度器的设计思路:
一是在一个物理Hadoop集群上虚拟多个Hadoop集群,这些集群各自有自己全套的Hadoop服务,典型的代表是HOD(Hadoop On Demand)调度器,Hadoop2.0中已经过时。
另一种是扩展YARN调度器。典型的是Capacity Scheduler、Fair Scheduler

  1. 基本架构

插拔式组件:YARN里的资源调度器是可插拔的,ResourceManager在初始化时根据配置创建一个调度器,可以通过参数yarn.resourcemanager.scheduler.class参数来设置调度器的主类是哪个,默认是CapacityScheduler,配置值为:org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler。
所有的资源调度器都要实现接口:org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler。
事件处理器:YARN的资源管理器实际上是一个事件处理器,它处理6个SchedulerEventType类型的事件。
事件说明:

  • Node_Removed 集群中移除一个计算节点,资源调度器需要收到该事件后从可分配的资源总量中移除相应的资源量。
  • Node_Added 集群增加一个节点
  • Application_added RM收到一个新的Application。
  • Application_Remove 表示一个Application运行结束
  • Container_expired 当一个Container分配给AM后,如果在一段时间内AM没有启动Container,就触发这个事件。调度器会对该Container进行回收。
  • Node_Update RM收到NM的心跳后,就会触发Node_Update事件。

    4.1 资源调度三种模型介绍

    究竟使用哪种调度模型,取决于这个配置项,apache版本的hadoop默认使用的是capacity scheduler调度方式CDH版本的默认使用的是fair scheduler调度方式 : yarn-site.xml

    yarn.resourcemanager.scheduler.class

  1. 双层资源调度模型

YARN使用了双层资源调度模型。

  • 第一层:ResourceManager中的调度器将资源分配给各个ApplicationMaster。这一层调度由YARN的资源调度器来实现。
  • 第二层:ApplicationMaster再进一步将资源分配给它内部的各个任务。这一层的调度由用户程序这个计算框架来实现。

YARN的资源分配过程是异步的,YARN的调度器分配给AM资源后,先将资源存入一个缓冲区内,当AM下次心跳时来领取资源。资源分配过程如下7个步骤:

  • 步骤1:NodeManager通过周期性的心跳汇报节点信息 : 告诉resourceManager当前剩余的资源信息。
  • 步骤2:RM为NM返回一个应答,包括要释放的Container列表。
  • 步骤3:RM收到NM汇报的信息后,会出发资源调度器的Node_Update事件。
  • 步骤4:资源调度器收到Node_Update事件后,会按照一定的策略将该节点上资源分配给各个应用程序,并将分配结果存入一个内存数据结构中。
  • 步骤5:应用程序的ApplicationMaster周期性地向RM发送心跳,以领取最新分配的Container。
  • 步骤6:RM收到AM的心跳后,将分配给它的Container以心跳应答的方式返回给ApplicationMaster。
  • 步骤7:AM收到新分配的Container后,会将这些Container进一步分配给他的内部子任务。
  1. 资源保证机制

YARN采用增量资源分配机制来保证资源的分配。
增量资源分配机制是指当YARN暂时不能满足应用程序的资源要求时,将现有的一个节点上的资源预留,等到这个节点上累计释放的资源满足了要求,再分配给ApplicationMaster。
这种增量资源分配机制虽然会造成资源的浪费,但是能保证AM肯定会得到资源,不会被饿死。

  1. 资源分配算法

YARN的资源调度器采用了主资源公平调度算法(DRF)来支持多维度资源调度。

  1. 资源抢占模型

资源调度器中,每个队列可以设置一个最小资源量和最大资源量。为了提高集群使用效率,资源调度器会将负载较轻的队列资源分配给负载较重的队列使用,当负载较轻的队列突然接到了新的任务时,调度器才会将本属于该队列的资源分配给它,但是此时资源有可能正被其他队列使用,因此调度器必须等待其他队列释放资源,如果一段时间后发现资源还未得到释放,则进行资源抢占。
关于资源抢占的实现,涉及到一下两个问题:

  • 如何决定是否抢占某个队列的资源
  • 如何使得资源抢占代价最小

资源抢占是通过杀死正在使用的Container实现的,由于Container已经处于运行状态,直接杀死Container会造成已经完成的计算白白浪费,为了尽可能地避免资源浪费,YARN优先选择优先级低的Container做为资源抢占的对象,并且不会立刻杀死Container,而是将释放资源的任务留给ApplicationMaster中的应用程序,以期望他能采取一定的措施来执行释放这些Container,比如保存一些状态后退出,如果一段时间后,ApplicationMaster仍未主动杀死Container,则RM再强制杀死这些Container。

4.1.1 FIFO调度策略

image.png
Hadoop1.0中使用了平级队列的组织方式,而后来采用了层级队列的组织方式。
层级队列的特点:

  • 子队列

队列可以嵌套,每个队列都可以包含子队列;用户只能将应用程序提交到叶子队列中。

  • 最小容量

每个子队列均有一个最小容量比属性,表示可以使用的父队列容量的百分比。调度器总是优先选择当前资源使用率最低的队列,并为之分配资源。指定了最小容量,但是不会保证会保持最小容量,同样会被分配给其他队列。

  • 最大容量

队列指定了最大容量,任何时候队列使用的资源都不会超过最大容量。默认情况下队列的最大容量是无限大。

  • 用户权限管理

管理员可以配置每个叶子节点队列对应的操作系统的用户和用户组。

  • 系统资源管理

管理员设置了每个队列的容量,每个用户可以用资源的量,调度器根据这些配置来进行资源调度
队列命名规则:为了防止队列名称的冲突和便于识别队列,YARN采用了自顶向下的路径命名规则,父队列和子队列名称采用.拼接。

4.1.2 Capacity Scheduler

image.png
image.png
Capacity Scheduler是Yahoo开发的多用户调度器。主要有以下几个特点:

  • 多队列

每个队列可配置一定的资源量,每个队列采用FIFO调度策略。

  • 容量保证

管理员可以为队列设置最低保证和资源使用上限,同一个队列里的应用程序可以共享使用队列资源。

  • 灵活性:

一个队列里的资源有剩余,可以暂时共享给其他队列,一旦该队列有的新的任务,其他队列会归还资源,这样尽量地提高了集群的利用率。

  • 多重租赁

支持多用户共享集群和多应用程序同时运行,为了防止同一个用户的作业独占队列中的资源,该调度器会对同一用户提交的作业所占资源量做限定。

  • 安全保证

每个队列有严格的ACL列表,限制了用户的权限。

  • 动态更新配置文件

管理员对参数的配置是动态的。
配置方案:
Capacity Scheduler的所有配置都在capactiy-scheduler.xml里,管理员修改后,要通过命令来刷写队列:yarn mradmin –refreshQueues
Capacity Scheduler不允许管理员动态地减少队列数目,且更新的配置参数值应该是合法值。
以下以队列tongyong为例来说明参数配置:
【资源分配相关参数】

  1. <property>
  2. <name>yarn.scheduler.capacity.root.tongyong.capacity</name>
  3. <value>10</value>
  4. <description>队列资源容量百分比</description>
  5. </property>
  6. <property>
  7. <name>yarn.scheduler.capacity.root.tongyong.user-limit-factor</name>
  8. <value>3</value>
  9. <description>
  10. 每个用户最多可以使用的资源量百分比
  11. </description>
  12. </property>
  13. <property>
  14. <name>yarn.scheduler.capacity.root.tongyong.maximum-capacity</name>
  15. <value>30</value>
  16. <description>
  17. 队列资源的使用的最高上限,由于存在资源共享,所以队列使用的资源可能会超过capacity设置的量,但是不会超过maximum-capacity设置的量
  18. </description>
  19. </property>
  20. <property>
  21. <name>yarn.scheduler.capacity.root.tongyong.minimum-user-limit-percent</name>
  22. <value>30</value>
  23. <description>用户资源限制的百分比,当值为30时,如果有两个用户,每个用户不能超过50%,当有3个用户时,每个用户不能超过33%,当超过三个用户时,每个用户不能超过30%
  24. </description>
  25. </property>

【限制应用程序数目相关参数】

  1. <property>
  2. <name>yarn.scheduler.capacity.root.tongyong.maximum-applications</name>
  3. <value>200</value>
  4. <description>
  5. 队列中同时处于等待和运行状态的应用程序的数量,如果多于这个数量的应用程序将被拒绝。
  6. </description>
  7. </property>
  8. <property>
  9. <name>yarn.scheduler.capacity.root.tongyong.maximum-am-resource-percent</name>
  10. <value>0.1</value>
  11. <description>
  12. 集群中用于运行应用程序ApplicationMaster的资源比例上限,该参数通常用于限制处于活动状态的应用程序的数目。
  13. </description>
  14. </property>

【队列的访问和权限控制参数】

  1. <property>
  2. <name>yarn.scheduler.capacity.root.tongyong.state</name>
  3. <value>RUNNING</value>
  4. <description>
  5. 队列状态,可以为STOPPED或者为RUNNING。如果改为STOPPED,用户将不能向集群中提交作业,但是正在运行的将正常结束。
  6. </description>
  7. </property>
  8. <property>
  9. <name>yarn.scheduler.capacity.root.tongyong.acl_submit_applications</name>
  10. <value>root,tongyong,user1,user2</value>
  11. <description>
  12. 限定哪些用户可以向队列里提交应用程序,该属性有继承性,子队列默认和父队列的配置是一样的。
  13. </description>
  14. </property>
  15. <property>
  16. <name>yarn.scheduler.capacity.root.tongyong.acl_administer_queue</name>
  17. <value>root,tongyong</value>
  18. <description>
  19. 限定哪些用户可以管理当前队列里的应用程序。
  20. </description>
  21. </property>

4.1.2.1 分配算法

image.png

4.1.3 Fair Scheduler

image.png
基本特点:

  1. 资源公平共享

默认是Fair策略分配资源,Fair 策略是一种基于最大最小公平算法实现的,所有应用程序平分资源。

  1. 支持资源抢占

某个队列中有剩余资源时,调度器会将这些资源共享给其他队列,当该队列有了新的应用程序提交过来后,调度器会回收资源,调度器采用先等待再强制回收的策略。

  1. 负载均衡

Fair Scheduler提供了一个基于任务数目的负载均衡机制,尽可能将系统中的任务均匀分布到各个节点上。

  1. 调度策略配置灵活

可以每个队列选用不同的调度策略:FIFO、Fair、DRF。

  1. 提高小应用程序的响应时间

小作业也可以分配大资源,可以快速地运行完成。
公平调度器与容量调度器相同点?

  1. 多队列:支持多队列多作业
  2. 容量保证:管理员可为每个队列设置资源最低保证和资源使用上限
  3. 灵活性:如果一个队列中的资源有剩余,可以暂时共享给那些需要资源的队列,而一旦该队列有新的应用程序提交,则其他队列借调的资源会归还该队列
  4. 多租户:支持多用户共享集群和多应用程序同时运行,为了防止同一个用户的作业独占队列中的资源,该调度器会对同一用户提交的作业所占资源量做限定。

公平调度器与容量调度器相同点?

  1. 核心调度策略不同

容量调度器:优先选择资源利用率低的队列
公平调度器:优先选择对资源缺额比例大的

  1. 每个队列可以单独设置资源分配方式

容量调度器:FIFO、DRF
公平调度器:FIFO、FAIR、DRF

缺额:某一时刻一个作业应获取资源和实际获取资源的差值 调度器会优先对缺额大的作业分配资源

4.1.3.1 资源分配算法

image.png
image.png
image.png

5. Yarn的多租户配置实现资源隔离

资源隔离目前有2种,静态隔离和动态隔离。
静态隔离:所谓静态隔离是以服务隔离,是通过cgroups(LINUX control groups) 功能来支持的。比如HADOOP服务包含HDFS, HBASE, YARN等等,那么我们固定的设置比例,HDFS:20%, HBASE:40%, YARN:40%, 系统会帮我们根据整个集群的CPU,内存,IO数量来分割资源,先提一下,IO是无法分割的,所以只能说当遇到IO问题时根据比例由谁先拿到资源,CPU和内存是预先分配好的。
上面这种按照比例固定分割就是静态分割了,仔细想想,这种做法弊端太多,假设我按照一定的比例预先分割好了,但是如果我晚上主要跑mapreduce,白天主要是HBASE工作,这种情况怎么办? 静态分割无法很好的支持,缺陷太大,这种模型可能不太合适。
动态隔离:动态隔离只要是针对 YARN以及impala,所谓动态只是相对静态来说,其实也不是动态。 先说YARN, 在HADOOP整个环境,主要服务有哪些? mapreduce(这里再提一下,mapreduce是应用,YARN是框架,搞清楚这个概念),HBASE, HIVE,SPARK,HDFS,IMPALA,实际上主要的大概这些,很多人估计会表示不赞同,oozie, ES, storm , kylin,flink等等这些和YARN离的太远了,不依赖YARN的资源服务,而且这些服务都是单独部署就OK,关联性不大。 所以主要和YARN有关也就是HIVE, SPARK,Mapreduce。这几个服务也正式目前用的最多的(HBASE用的也很多,但是和YARN没啥关系)。
根据上面的描述,大家应该能理解为什么所谓的动态隔离主要是针对YARN。好了,既然YARN占的比重这么多,那么如果能很好的对YARN进行资源隔离,那也是不错的。如果我有3个部分都需要使用HADOOP,那么我希望能根据不同部门设置资源的优先级别,实际上也是根据比例来设置,建立3个queue name, 开发部们30%,数据分析部分50%,运营部门20%。
设置了比例之后,再提交JOB的时候设置mapreduce.queue.name,那么JOB就会进入指定的队列里面。 非常可惜的是,如果你指定了一个不存在的队列,JOB仍然可以执行,这个是目前无解的,默认提交JOB到YARN的时候,规则是root.users.username , 队列不存在,会自动以这种格式生成队列名称。 队列设置好之后,再通过ACL来控制谁能提交或者KIll job。

从上面2种资源隔离来看,没有哪一种做的很好,如果非要选一种,建议选取后者,隔离YARN资源, 第一种固定分割服务的方式实在支持不了现在的业务。

需求:现在一个集群当中,可能有多个用户都需要使用,例如开发人员需要提交任务,测试人员需要提交任务,以及其他部门工作同事也需要提交任务到集群上面去,对于我们多个用户同时提交任务,我们可以通过配置yarn的多用户资源隔离来进行实现。

  1. node01编辑yarn-site.xml ```xml yarn.resourcemanager.scheduler.class org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler
yarn.scheduler.fair.allocation.file /etc/hadoop/fair-scheduler.xml yarn.scheduler.fair.preemption true yarn.scheduler.fair.preemption.cluster-utilization-threshold 0.8f yarn.scheduler.fair.user-as-default-queue true default is True

yarn.scheduler.fair.allow-undeclared-pools false default is True

  1. 2. node01添加fair-scheduler.xml配置文件
  2. ```xml
  3. <?xml version="1.0"?>
  4. <allocations>
  5. <!-- users max running apps -->
  6. <userMaxAppsDefault>30</userMaxAppsDefault>
  7. <!-- 定义我们的队列 -->
  8. <queue name="root">
  9. <minResources>512mb,4vcores</minResources>
  10. <maxResources>102400mb,100vcores</maxResources>
  11. <maxRunningApps>100</maxRunningApps>
  12. <weight>1.0</weight>
  13. <schedulingMode>fair</schedulingMode>
  14. <aclSubmitApps> </aclSubmitApps>
  15. <aclAdministerApps> </aclAdministerApps>
  16. <queue name="default">
  17. <minResources>512mb,4vcores</minResources>
  18. <maxResources>30720mb,30vcores</maxResources>
  19. <maxRunningApps>100</maxRunningApps>
  20. <schedulingMode>fair</schedulingMode>
  21. <weight>1.0</weight>
  22. <!-- 所有的任务如果不指定任务队列,都提交到default队列里面来 -->
  23. <aclSubmitApps>*</aclSubmitApps>
  24. </queue>
  25. <!--
  26. weight
  27. 资源池权重
  28. aclSubmitApps
  29. 允许提交任务的用户名和组;
  30. 格式为: 用户名 用户组
  31. 当有多个用户时候,格式为:用户名1,用户名2 用户名1所属组,用户名2所属组
  32. aclAdministerApps
  33. 允许管理任务的用户名和组;
  34. 格式同上。
  35. -->
  36. <queue name="hadoop">
  37. <minResources>512mb,4vcores</minResources>
  38. <maxResources>20480mb,20vcores</maxResources>
  39. <maxRunningApps>100</maxRunningApps>
  40. <schedulingMode>fair</schedulingMode>
  41. <weight>2.0</weight>
  42. <aclSubmitApps>hadoop hadoop</aclSubmitApps>
  43. <aclAdministerApps>hadoop hadoop</aclAdministerApps>
  44. </queue>
  45. <queue name="develop">
  46. <minResources>512mb,4vcores</minResources>
  47. <maxResources>20480mb,20vcores</maxResources>
  48. <maxRunningApps>100</maxRunningApps>
  49. <schedulingMode>fair</schedulingMode>
  50. <weight>1</weight>
  51. <aclSubmitApps>develop develop</aclSubmitApps>
  52. <aclAdministerApps>develop develop</aclAdministerApps>
  53. </queue>
  54. <queue name="test1">
  55. <minResources>512mb,4vcores</minResources>
  56. <maxResources>20480mb,20vcores</maxResources>
  57. <maxRunningApps>100</maxRunningApps>
  58. <schedulingMode>fair</schedulingMode>
  59. <weight>1.5</weight>
  60. <aclSubmitApps>test1,hadoop,develop test1</aclSubmitApps>
  61. <aclAdministerApps>test1 group_businessC,supergroup</aclAdministerApps>
  62. </queue>
  63. </queue>
  64. </allocations>
  1. 将修改后的配置文件拷贝到其他机器上

    1. > cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
    2. > scp yarn-site.xml fair-scheduler.xml node02:$PWD
    3. > scp yarn-site.xml fair-scheduler.xml node03:$PWD
  2. 重启yarn集群

    1. > cd /export/servers/hadoop-2.6.0-cdh5.14.0/
    2. > sbin/stop-yarn.sh
    3. > sbin/start-yarn.sh
  3. 创建普通用户hadoop

    1. > useradd hadoop
    2. > passwd hadoop
  4. 修改文件夹权限

node01执行以下命令,修改hdfs上面tmp文件夹的权限,不然普通用户执行任务的时候会抛出权限不足的异常。

  1. > groupadd supergroup
  2. > usermod -a -G supergroup hadoop
  3. > su - root -s /bin/bash -c "hdfs dfsadmin -refreshUserToGroupsMappings"
  1. 使用hadoop用户提交mr任务

node01执行以下命令,切换到普通用户hadoop,然后使用hadoop来提交mr的任务。

  1. > su hadoop
  2. > yarn jar /export/servers/hadoop-2.6.0-cdh5.14.0/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.14.0.jar pi 10 20

6. Yarn生产环境核心参数

image.png