2、MapReduce与YARM

版权声明: https://blog.csdn.net/KamRoseLee/article/details/83894080

 

MapReduce 离线计算引擎

 

一、Mapreduce 的基本概念

 

Mapreduce 是一个分布式的计算框架,提供计算的模型,框架和平台,它易于编程,我们在进行功能组件开发的时候只需要通过代码表达我们需要做什么就可以,具体的计算和操作交由执行框架进行处理即可。如果平台性能无法满足我们的需求的时候,我们只需要按需拓展我们的节点,通过 Scale-out 来进行性能线性拓展,而本身平台又提供了高容错性,我们可以通过计算迁移或者数据迁移操作,当节点出现故障的时候不会影响我们的现有业务。

 

它包含以下三层含义:

 

(1)MapReduce 是基于集群的高性能并行计算平台(ClusterInfrastructure)。这里主要是指其在 Hadoop 中作为一个组件被使用,MapReduce 在大数据平台中提供的是一个离线的分布式计算引擎。其可以和底层的存储相关的组件进行交互,将文件进行计算和其他相关的操作。

 

(2)MapReduce 是一个并行计算与运行软件框架(SoftwareFramework)。

 

作为一个软件框架,MapReduce 主要是被使用在编程语句中,进行相关的软件编译,比如其在 Python 中就作为了一个语句固件被编程者使用。

 

(3)MapReduce 是一个并行程序设计模型(ProgrammingModel&Methodology)。在早期谷歌提出 MapReduce 的设计思想时,其实它并没有一个专门的作用领域,而是作为一个思想来使用,它提供了计算的方法,所以在实际中,我们还可以按照这种设计模型和思想进行其他相关的开发。

MapReduce 具有如下的特点:

 

(1)易于编程:程序员仅需描述做什么,具体怎么做交由系统的执行框架处理。(2)良好的扩展性:可通过添加节点以扩展集群能力。

 

(3)高容错性:通过计算迁移或数据迁移等策略提高集群的可用性与容错性。

 

MapReduce 从诞生到目前的发展中主要的版本有以下几个:MR1.3.0、MR1.3.1、MR1.5.0、MR1.5.1,但是在 MapReducev1 中,也同时存在以下几个致命性的缺点:(1)拓展性受限,由于 MapReduce 在早期需要自己去维护节点,所以 Mapreduce 虽然拓展性很好,但是拓展是有限度的,无法进行无限的拓展。

 

MapReduce 作为一个计算引擎,其在早期的设计思路中,由于是独立于所有组件存在的所以他除了需要进行相关的计算操作以外,还需要对自己所搭载的平台进行相关的维护操作。这样的话,MapReduce 除了计算就还要对设备提供一部分的资源进行维护操作,那么设备越多我们为了维护设备所需要从 MapReduce 中提供的资源也就越多。这样的话,设备多虽然可以提高计算的效率,但是设备数目过大的时候,维护的开销就会高于设备所能提供的资源了。这样就会到达一个平衡点。也就是指 MapReduce 在这种情况下就无法无限拓展了,所以其能够计算的数据也就有了上限,但是这样的话,就无法满足数据增长的计算需求。

 

(2)单点故障:MapReduce 是部署在单个节点上的,所以一旦出现问题之后, MapReduce 就会直接无法使用,产生单点故障由于早期的 MapReduce 是一个单进程的引擎,和其他的组件不同的是,其他组件

 

都会有对应的保护措施,不管是对进程还是对数据,那么 MapReduce 没有提供任何的保护机制,一旦计算出现问题,那么就直接中断。MapReduce 作为一个离线

计算引擎,其主要提供的是针对于大量的数据的计算工作,计算的周期会很长,那么一旦出现问题,计算中断就会导致之前的计算全部失效。

 

(3)不支持 MR 之外的计算:MapReduce 只支持离线计算,对于在线计算和流处理计算的大量需求无法满足,也就导致了其计算的滞后性。

 

这里主要想要表达的是 MapReduce 对于计算引擎之间的低效问题。由于 MapReduce 本身只提供对海量文件的计算,那么从其设计的角度上来讲,就是提供大量文件的计算操作。对于延迟敏感型的业务或者是有其他相关需求的计算都是无法满足的,那么这样就会导致其出现计算的单一性,没有很广泛的适用性。(4)计算框架之间无法进行共享,资源利用率低:目前我们使用的计算引擎主要有 MapReduce、Storm、Spark 等,不同的框架采用的不同的计算方法,框架之间 MapReduce 不支持进行数据共享就导致了其对于资源的利用率过低的问题。

如上图所示:由于在早期,我们的存储组件是直接对接的计算引擎的,而计算引擎之间又无法做相关的共享操作,所以这个时候如果组件与组件之间需要做相关的数据共享,或者中间结果共享,那么就会出现问题,MapReduce 作为计算引擎必须将自己的计算结果先存入到底层的存储组件中,才能被其他组件调用到,那么数据下盘第一个会造成的问题在于,这里的数据作为一个临时结果对于 HDFS 等存储组件来说,认知就是一个数据,那么就会启用对应的保护机制,以及元数据修改等操作,而且本身数据下盘就要消耗时间,所以整个流程,会耗费掉大量的时间,而且一个计算过程中间会出现多次调用,那么这种过程就会持续多次,整体的进程非常消耗相关的计算资源,而且如果这些组件都部署在一台节点上,本身在内存中进行数据转换就可以完成的事情,这里必须要执行相当复杂的操作才能执行完成。所以资源的利用率和任务的执行时间都是非常的差的。

 

 

二、Yarn 简介

 

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

 

Yarn 的出现主要是为了解决上边我们说到的 MapReduce v1 版本的问题,其实 MapReduce 的问题也是同样出现在其他的计算引擎中的,所以 Yarn 的出现不仅仅是解决了 MapReduce 的问题还将以往离散的不关联的各个组件在底层柔和为了一体,那么 Yarn 主要带来了以下的几个好处:

(1)增大拓展性:前面说到拓展性的受限主要是由于计算引擎需要自身去维护节点,那么 Yarn 第一步就将节点的维护作业从引擎身上卸载到 Yarn 来做,以往每个引擎都需要自身去维护,可能一个节点安装了 5 个计算引擎,那么 5 个计算引擎就会有 5 个节点维护进程,现在交由 Yarn 做之后,就会将这些进程全部卸载到自身,糅合成了一个进程来统一进行维护,这样做就减小了计算引擎的其他工作,减少了引擎的额外开销。

 

(2)单点故障:Yarn 的第二个作用就是解决了单点故障的问题,yarn 将计算引擎的任务也卸载到了自身,这样传统的计算引擎就不需要对计算的任务进行规划和控制了,一方面减小了开销,另一方面也有利于引擎与引擎之间的计算共享,任务管理不再交由计算引擎来进行维护,而是交由 Yarn 来进行。如果传统的计算引擎需要执行跨引擎的计算,一方面会无法监控任务的执行状态,另一方面,如果跨引擎执行计算,那么引擎还需要额外的分配一部分资源来做跨引擎的计算维护,反而消耗的资源会更多。当 Yarn 将整体任务规划执行监控卸载到自身之后,一方面会增大各个计算组件之间的兼容性和控制能力,另一方面如果计算引擎出现故障,任务就不会再丢失,Yarn 就可以根据执行的进度,重新下发任务,思想很类似于网络中的断点重传。

 

(3)计算框架之间的共享:Yarn 的出现屏蔽了计算引擎之间的差异,主要是从任务、资源以及数据上,任务的屏蔽在第二条已经写出,那么资源的屏蔽主要体现在传统的计算引擎中,每个计算引擎都会维护自身的资源,这个时候如果某一一引擎有突发的计算,其他的引擎是无法共享相关的资源,当 Yarn 出现之后,它将所有引擎的资源进行了整合,这样做有利于进行统一调配实现高利用率,而且还节省了计算引擎的开销。另外传统的计算引擎在数据上无法共享,那么 Yarn 接管了资源和任务相关的管理权限之后,所有计算引擎的计算临时结果都是缓存在 yarn 管理的资源上,这个时候,我们的临时数据就不需要在执行写入操作,直接在内存中进行资源分配, 将包含数据的那一部分内存直接调用给其他引擎进行使用,就可以实现内存中的数据转换和跨引擎调用。

三、Yarn 架构

 

ResourceManager(RM):负责集群中所有资源的统一管理和分配。它接收来自各个节点(NodeManager)的资源汇报信息,并根据收集的资源按照一定的策略分配给各个应用程序。

 

RM 作为资源的管理者,其只对资源做管理,不对资源做维护,资源主要涉及的

是内存和 CPU 资源。所有的应用在被提交之后首先第一步都是需要做资源的申请的。业务提交之后会根据自身的资源消耗情况向 RM 做申请,RM 需要做资源的分配,以及资源的回收监控。

 

NodeManager(NM):是每个节点上的代理,它管理 Hadoop 集群中单个计算节点,包括与 ResourceManger 保持通信,监督 Container 的生命周期管理,监控每个 Container 的资源使用(内存、CPU 等)情况,追踪节点健康状况,管理日志和不同应用程序用到的附属服务(auxiliary service)。

 

这里我们说 RM 本身是资源的管控者,资源是在 NM 上的,相当于 NM 实际拥有这些资源,但是管理权和所有权是归属于 RM 的,就像买房,土地是国家的,产权是自己的。NM 需要上报自己的资源拥有状况给 RM,RM 在根据相关任务情况,对这些资源做统一的分配操作。

 

Application Master(AM):负责一个 Application 生命周期内的所有工作。包括:与 RM 调度器协商以获取资源;将得到的资源进一步分配给内部任务(资源的二次分配);与 NM 通信以启动/停止任务;监控所有任务运行状态,并在任务运行失败时重新为任务申请资源以重启任务。

 

Container:Yarn 中的资源抽象,它封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等。

 

容器是在 MapReduce 中执行任务的工作单位,其是一个资源的集合体,它是一个逻辑的概念,使用的时候将其分配创建,任务执行完毕之后,就会将容器回收,容器回收就是指回收容器中的 CPU 和内存资源。RM 分配 NM 的资源,在 NM 上创建一个 CPU 和内存的集合体,这个集合体就是 Container。

 

NodeManager 主要工作是节点资源管理监控和容器管理,RM 是系统中将资源分配给各个应用的最终决策者。

 

四、MapReduce 在 Yarn 中的任务调度

(1)用户向 YARN 中提交应用程序, 其中包括 ApplicationMaster 程序、启动 ApplicationMaster 的命令、用户程序等。

 

这里 Client 还是一个进程,并非是用户的程序,Client 用于提交执行应用,对用户提供一个可以进行访问的接口,用户通过该接口连接到 MapReduce 服务,然后提交对应的应用,然后 Client 将应用转发到 RM 上进行进一步的操作,应用是由用户的程序进行封装之后的一个执行包,该执行包中需要有以下的内容,AMaster(用于进行应用的资源申请,分配,管理等操作,在整个业务执行的过程中都会被使用,AMaster 和其他的组价进行交互,完成相关的作业),Amaster相关的附属命令以及我们所需要执行的具体程序。

 

( 2) ResourceManager 为该应用程序分配第一个 Container,并与对应的 NodeManager 通 信 , 要 求 它 在 这 个 Container 中 启 动 应 用 程 序 的ApplicationMaster。

 

RM 中有两个主要的子进程,一个是 AppManager,一个是 ResourceScheduler, AppManager 主要是对提交到引擎上的多个应用进行一个统一集中的管理,保证整体业务的执行。ResourceScheduler 是用于管理和监控资源的进程,它用于分配资源,管理资源,监控资源和回收资源。用户将应用提交之后,首先第一步, RM 会根据用户提交的应用中关于 AppMaster 的信息,为其分配一部分的内存和 CPU 的资源,然后通告对应 NM 节点,在其身上拉起一个 Container,由于 Appmaster 本身也是一个程序,需要消耗资源,所以其会在 RM 分配 NM 拉起的这个 Container 中运行 AppMaster。

(3)ApplicationMaster 首先向 ResourceManager 注册,这样用户可以直接通过 ResourceManage 查看应用程序的运行状态,然后它将为各个任务申请资源,并监控它的运行状态,直到运行结束,即重复步骤 4~7。

 

AppMaster 启动之后,首先第一步需要向 AppManager 去进行相关的注册操作,否则 Appmaster 将会是一个非法的程序。

 

(4)ApplicationMaster 采用轮询的方式通过 RPC 协议向 ResourceManager 申

 

请和领取资源。

 

AppMaster 注册之后,根据设计的思想,它首先第一步会将程序做切分,分为执行的阶段,最终切分为执行的一个个计算工作,我们称之为 task,之后它会计算当前的 task 所需要消耗资源,然后向 ResourceScheduler 进行资源的申请操作,ResourceScheduler 同意之后将和 NM 进行通信,通知 NM 分配相关的资源使用权给 AppMaster。

 

(5)一旦 ApplicationMaster 申请到资源后,便与对应的 NodeManager 通信,要求它启动任务。

 

AppMaster 获取到使用权之后,就会和 NM 进行通信,要求 NM 将对应的资源封装为 Container,然后拉起,随后 AppMaster 会将对应的 task 下发到 Container 中

 

进行执行计算。AppMaster 会采用轮询的方式,也就是指,资源并不是根据程序所需要消耗的量一次性申请的,而是根据 task 消耗的资源,一个一个进行的申请,RM 在收到对应的申请请求时,会根据当前 NM 的负载情况(资源的分配情况,以及当前计算的开销),随机的选择当前负载最低的 NM,将其资源分配给

AppMaster

 

(6)NodeManager 为任务设置好运行环境(包括环境变量、JAR 包、二进制程序等)后,将任务启动命令写到一个脚本中,并通过运行该脚本启动任务。

(7)各个任务通过某个 RPC 协议向 ApplicationMaster 汇报自己的状态和进度,以让 ApplicationMaster 随时掌握各个任务的运行状态,从而可以在任务失败时重新启动任务。

 

在应用程序运行过程中,用户可随时通过 RPC 向 ApplicationMaster 查询应用程序的当前运行状态。在 task 执行完成之后,Container 会自己关闭,然后 NM 就会感知到资源释放,随后和 RM 通信时,就会反馈资源已经处于可分配的状态。(8)应用程序运行完成后,ApplicationMaster 向 ResourceManager

(AppManager)注销并关闭自己。

五、Yarn 通信协议

Application Client Protocol :JobClient 通过该 RPC 协议提交应用程序、查询应用程序状态等。

 

Resource Manager Administration Protocol:Admin 通过该 RPC 协议更新系统配置文件,比如节点黑白名单、用户队列权限等。

 

Application Master Protocol :AM 通过该 RPC 协议向 RM 注册和撤销自己,并为各个任务申请资源。

 

Container Management Protocol : AM 通过该 RPC 要求 NM 启动或者停止Container,获取各个 Container 的使用状态等信息。

 

Resource Tracker :NM 通过该 RPC 协议向 RM 注册,并定时发送心跳信息汇报当前节点的资源使用情况和 Container 运行情况。

六、MapReduce 过程详解

Job 的创建、申请与 Map 流程:

 

(1)首先在进行启动 MapReduce 计算前,我们先保证数据在 HDFS 中,避免由于文件不存在导致的处理失败(2)确认文件存在之后,我们下一步就需要做任务的提交工作,应用将工作提

 

交给 RM 模块进行处理,RM 模块会针对请求创建 Job,每个应用的请求都会有一个唯一的 JobID 进行区分。

 

我们将工作提交给 Client 之后,Client 会接收相关的数据并且将数据提交给 RM

模块,RM 模块收到之后,首先第一步需要创建一个 job 并且分配 jobID。这里的 JobID 主要是用于区分业务,我们可以记录相关的操作日志。用于区分。

 

(3)Job 创建完成之后,我们会将待处理的文件进行分片操作,通过分片,我们将分片与 MapTask 进行一一对应。

 

在我们对应用分配了 JobID 之后,在 job 在进行提交之前,首先会将文件进行分片的操作。由于整体文件一般过大,没有某一个节点可以完全执行计算的操作,那么我们就需要将文件进行切分,然后将任务打散在不同的设备上去执行,这样也体现了 MapReduce 的分布式的特点。我们默认一个分片对应的就是一个 task (这里的 Task 就是用于执行输入的 MapTask),每个 task 会携带一个 key 值。(4)分片完成之后,下一步就是提交 Job,RM 会根据收到的 Job 和 NM 模块目前的负载选择合适的 NM 去调度 AM,AM 在收到 Job 之后,会对工作进行初始化,衡量计算所需的资源并向 RM 申请,RM 收到申请之后,将会针对 task 调度某一些

NM 模块启动 Container 进程来执行 task 任务。

 

计算与 Reduce 进程:

 

(1)Map 输入的资源在计算完成之后,暂存在一个环形缓存分区中,当缓存分区写满,最前端的数据就会溢出写入到本地磁盘中,触发 Reduce 进程 Map 任务主要执行的就是数据的输入,切分,以及计算的操作,计算中会产生大量的临时结果,这个时候我们就需要将这些文件存储在内存中,进行第一步的缓存操作,我们在内存中分配了一个环形的内存缓冲区进行数据的临时存放,缓冲区是一个有大小限制的空间,它是一个逻辑的概念,实际上是一个连续的内存分配地址。数据按照先后顺序入栈,那么一旦缓冲区写满,最前端的也就是最先入栈的数据,就会溢出,溢出之后我们就会将这些临时的数据进行下盘操作进行存储,因为内存的大小是有限的,而且临时文件又很多,所以我们无法保证所有的临时文件都存储在内存中,而且进程本身又占用了部分的内存所以我们需要进行这个出入栈的缓存操作。

(2)在进行 Reduce 输出之前,由于我们在计算中产生了很多的临时文件,那么文件过于碎片化,就会在导出时影响整体的导出效率,所以在输出之前,我们可选执行以下几个操作:分区,排序,组合,合并(这些操作都是针对于执行相关的结果内容的)

 

①分区:MR 框架会根据 Reduce 进程的个数创建对应个数的分区,将相同 key 值的数据存放到同一个分区中。例如:一次计算进程被分为了多个 job 进行计算,那么输出的时候为了保证对应的数据最终被组合成唯一的计算结果,所以我们需

要对数据进行分区,那么每个 job 都会有一个 key 值保证最终的计算结果被存储到同一个分区中。

 

分区的主要作用就是用于对应结果的,我们将切片后的 Maptask 执行结果又按照 Key 值进行了归类,这样做就可以将具有相同 key 值的临时文件存放到同一个分区中,结果整合有利于减小输出的文件个数,对我们的执行结果输出更加有利。排序:根据 Map 的输出顺序,RM 模块会将 Reduce 计算出来的结果进行排序(可选)

 

③组合:根据用户的要求,可选将结果进行组合,最终产生一个总结果(可选)

 

④合并:由于计算之后会产生大量的数据,所以我们在写入数据的时候可以将文件进行合并操作,按照上边说的三种方式或者采用压缩方案,最终将溢出文件合并为 MOF 文件进行输出,MOF(MapOutputFile)

 

组合和合并的区别:组合是将我们执行的临时文件的结果进行整理和合并操作,组合会减小文件的大小,但是减小的是单个文件内的内容,所以单个文件的大小会缩减,但是合并是针对于溢出文件来进行一个文件级别的合并操作,所以合并做操作是减小整体所有文件所消耗的空间大小。所以我们可以理解为组合是对内容作的操作,合并是对文件做的操作。

 

(3)MOF 文件在进行输出的时候首先是放置在内存(这里所说的内存并不是之前所提到的内存的缓冲区,而是单独独立于环形内存缓冲区的新分配的一块内存区域)之中的,当 MOF 文件输出占任务总输出的 3%以上时,就会启动 reduce 进程,随着文件数的增加,我们针对文件进行分区、排序、组合、合并之后,将小的 MOF 文件逐步整合为大的 MOF 文件,直到最终最后一次 MOF 合并生成的就是输出结果。

总体来说:MapReduce 的进程分为 Map 进程和 Reduce 进程,主要进程为:commit、Split、Map、Sort/Merge、Reduce。在计算进程中又包含了针对临时文件的操作。进程之间相互协作完成对应的目标。

 

MapReduce 完全详细进程:

用户向 Client 提交应用执行请求

Client 收到请求之后,受理请求并且接收相关的数据

Client 会向 RM 提交申请

RM 受理申请并且创建和反馈 JobID

Client 将应用提交到 RM 上

RM 受理应用,并且启动 APPManager,启动之后,RM 会根据 NM 的负载情况,选择当前负载最小的 NM,通知其在自身启动一个容器,之后 RM 会将 APPMaster 下发到该容器中进行执行操作。

AppMaster 在启动之后,首先会向 AppManager 执行注册操作。之后会根据job,计算当前任务执行所需要的资源的总量,并且将 job 切分为 task,以 task 为单位向 RS 去申请。

RS 在收到请求之后,会检查当前集群内 NM 的负载情况,选择负载最低的 NM,并且向 AppMaster 返回对应的信息

AppMaster 在收到 RS 的确认信息之后,会要求该 NM 启动容器,并且将 task 进行发送。

NM 在拉起容器之后,将任务加入到容器中进行运行,运行完成之后其会将结果整合成临时文件反馈到 Appmaster 的内存中。AppMaster 的内存中会有一个环形临时缓冲区,各个 task 执行之后的临时文件都会在这里存储。当环形缓冲区溢出时,就会触发下一步的操作。

在进行下一步输出之前,首先要执行 4 步操作 11.1 分区:文件会按照哈希算法得到的 key 值进行分区,也就相当于根据分片

我们最终将相同分片的执行结果的临时文件放到相同的分区内。 11.2 排序:我们会将计算出的结果按照我们想要的格式进行排序操作

组合:多个结果之间可能会出现重复的情况,那么为了减小输出的文件大小,并且利于表达,我们可以选择执行组合的操作 合并:我们将分区内多个临时溢出文件进行整合,整合为 MOF 文件

 

整合为 MOF 文件之后,在 MOF 文件输出进度为 3%的时候我们就会启动 Reduce 进程。我们会将 MOF 文件做连续和合并和排序操作,直到最终整合为一个完 er资源,AppMaster 要向 AppManager 注销。并将执行结果通过 client 反馈给用户。

用户收到结果之后关闭应用,RM 将 JOBID 回收并且记录执行日志。

七、Yarn 的资源分配

 

当前 YARN 支持内存和 CPU 两种资源类型的管理和分配。每个 NodeManager 可分配的内存和 CPU 的数量可以通过配置选项设置(可在 yarn 服务配置页面配置)。(1)yarn.nodemanager.resource.memory-mb

用于当前 NodeManager 上正运行的容器的物理内存的大小。单位:MB。必须小于

NodeManager 服务器上的实际内存大小(2)yarn.nodemanager.vmem-pmem-ratio

为容器设置内存限制时虚拟内存跟物理内存的比值。容器分配值使用物理内存表示的,虚拟内存使用率超过分配值的比例不允许大于当前这个比例。

(3)yarn.nodemanager.resource.cpu-vcore可分配给 container 的 CPU 核数。建议配置为 CPU 核数的 1.5-2 倍。

 

资源分配模型:

调度器维护一群队列的信息。用户可以向一个或者多个队列提交应用。每次 NM 心跳的时候,调度器根据一定的规则选择一个队列,再在队列上选择一个应用,尝试在这个应用上分配资源。

 

调度器会优先匹配本地资源的申请请求,其次是同机架的,最后是任意机器的。当任务提交上来,首先会声明提交到哪个队列上,调度器会分配队列,如果没有指定则任务运行在默认队列。

队列是封装了集群资源容量的资源集合,占用集群的百分比例资源,队列分为父队列,子队列,任务最终是运行在子队列上的。父队列可以有多个子队列。调度器选择队列上的应用,然后根据一些算法给应用分配资源

八、容量调度器

容量调度器使得 Hadoop 应用能够共享的、多用户的、操作简便的运行在集群上,同时最大化集群的吞吐量和利用率。

容量调度器以队列为单位划分资源,每个队列都有资源使用的下限和上限。每个用户可以设定资源使用上限。管理员可以约束单个队列、用户或作业的资源使用。支持作业优先级,但不支持资源抢占。

特点:

容量保证:管理员可为每个队列设置资源最低保证和资源使用上限,所有提交到该队列的应用程序共享这些资源。

灵活性:如果一个队列中的资源有剩余,可以暂时共享给那些需要资源的队列,当该队列有新的应用程序提交,则其他队列释放的资源会归还给该队列。

支持优先级:队列支持任务优先级调度(默认是 FIFO)。

多重租赁:支持多用户共享集群和多应用程序同时运行。为防止单个应用程序、用户或者队列独占集群资源,管理员可为之增加多重约束。

动态更新配置文件:管理员可根据需要动态修改配置参数,以实现在线集群管理。任务选择:调度时,首先按以下策略选择一个合适队列:

资源利用量最低的队列优先,比如同级的两个队列 Q1 和 Q2,它们的容量均为 30,而 Q1 已使用 10,Q2 已使用 12,则会优先将资源分配给 Q1;

最小队列层级优先,例如:QueueA 与 QueueB.childQueueB,则 QueueA 优先;资源回收请求队列优先。

然后按以下策略选择该队列中一个任务:

按照任务优先级和提交时间顺序选择,同时考虑用户资源量限制和内存限制。

动态内存管理可用来优化 NodeManager 中 Containers 的内存利用率。任务在运行过程中可能产生多个 Container。

当前,当单个节点上的 Container 超过机器运行内存大小时,即使集群总的配置内存利用还很低,NodeManager 也会终止这些 Containers。这样就会经常使用户作业失败。

动态内存管理特性在当前是一个改进,只有当 NodeManager 中的所有 Containers 的总内存使用超过了已确定的阈值,那么那些内存使用过多的 Containers 才会被终止。NM 总内存阈值的计算方法是:

NM.MEM=yarn.nodemanager.resource.memory*1024*1024*yarn.nodemanager.dy namic.memory.usage.threshold、单位 GB NM.MEM=分配给容器运行任务的内存*1024*1024*nodemanager 动态内存使用阈值

举例,假如某些 Containers 的物理内存利用率超过了配置的内存阈值,但所有 Containers 的总内存利用率并没有超过设置的集群内存阈值,那么那些内存使用过多的 Containers 仍可以继续运行。

十、Yarn 的标签调度制度

在没有标签调度之前,任务提交到哪个节点上是无法控制的,会根据一些算法及条件,集群随机分配到某些节点上。而标签调度可以指定任务提交到哪些节点上。比如之前需要消耗高内存的应用提交上来,由于运行在那些节点不可控,任务可能运行在普通性能的机器上。Label based scheduling 是一种调度策略。该策略的基本思想是:用户可以为每个 nodemanager 标注一个标签,比如 high-memory, high-IO 等进行分类,以表明该 nodemanager 的特性;同时,用户可以为调度器中每个队列标注一个标签,即队列与标签绑定,这样,提交到某个队列中的作业, 只会使用标注有对应标签的节点上的资源,即任务实际运行在打有对应标签的节 点上。将耗内存消耗型的任务提交到绑定了 high-memry 的标签的队列上,那么任务就可以运行在高内存机器上。

十一、Yarn 的 AM 作业保留机制

在 YARN 中, ApplicationMaster(AM) 与其他 Container 类 似 也 运 行 在

NodeManager 上(忽略未管理的 AM)。AM 可能会由于多种原因崩溃、退出或关闭。如果 AM 停止运行,ResourceManager(RM)会关闭 ApplicationMaster 中管理的所有 Container,包括当前任务在 NodeManager(NM)上正在运行的所有Container。

RM 会在另一计算节点上启动新的 ApplicationMaster。不同类型的应用希望以多种方式处理 AM 重新启动的事件。MapReduce 类应用目标是不丢失任务状态,

但也能允许一部分的状态损失。但是对于长周期的服务而言,用户并不希望仅仅由 于 AM 的 故 障 而 导 致 整 个 服 务 停 止 运 行 。 YARN 支 持 在 新 的

ApplicationMaster 启动时,保留之前 Container 的状态,因此运行中的作业可以继续无故障的运行。

猜你喜欢

转载自blog.csdn.net/KamRoseLee/article/details/83894080