我爱编程

YARN源码解析(4)-ResourceManager, Nod

2018-03-07  本文已影响774人  AlstonWilliams

在之前的Hadoop版本中,是不存在ResourceManager, NodeManager的概念的,此时,只有JobTracker以及TaskTracker的概念。

但是,此时,在功能上,耦合度很高。YARN作为一个资源调度平台,却不是一个通用的平台,而是紧紧和MapReduce结合在一起。

后来,Hadoop的开发团队终于意识到,应当把YARN和MapReduce的实现独立出来,让YARN能够作为一个通用的资源调度平台。

而当Hadoop的开发团队把YARN抽离出来之后,之后YARN就是一片欣欣向荣的景象了。后来出现的好多分布式调度系统,都支持在YARN上进行调度。比如,Spark就同时支持YARN,Mesos等。

所以,在这篇文章中,我们将会介绍,再将YARN单独抽离出来之后,形成的三个组件-ResourceManager, NodeManager以及ApplicationMaster,它们各自的职责。

ResourceManager

YARN中,最重要的一个组件就是ResourceManager。实际上,严格来说,YARN只包含两个组件,ResourceManager以及NodeManager。而ApplicationMaster只是一个YARN的客户端。所以,在YARN中,实际上是不信任ApplicationMaster的。因为ApplicationMaster可以由用户自己实现,可能存在危险。

ResourceManager包含了很多组件,我们将它们分成几大类,和Client进行交互的组件,和ApplicationMaster交互的组件,和NodeManager交互的组件,其他核心组件,以及和安全相关的组件。

和Client进行交互的组件

和ApplicationMaster交互的组件

和NodeManager交互的组件

在注册了一个新的Node之后, ResourceManager就会给NodeManager发送一个和安全性相关的master key。然后,NodeManager用这个master key来验证ApplicationMaster发送给他的分配Container的请求。

这个master key也不是会一直不变的,为了防止恶意的ApplicationMaster破解master key并向NodeManager提交恶意的Container,所以这个master key会每隔一段时间变一次,并发送给NodeManager.

ResourceTrackerService会将有效的heartbeat转发给YARNScheduler,然后YARNScheduler会根据集群中可用的资源,进行容器的分配。

其他核心组件

除了上面我们已经介绍的一些组件,还有一些比较核心的组件。

这个组件也负责在一个Application完成后以及被完全清理之前,管理它们。当一个Application完成后,它会生成一个ApplicationSummary,并将它记录到daemon的日志文件中。

ResourceManager中有一个属性-'yarn.resourcemanager.max-completed-applications',这个属性控制ResourceManager最多能够维护多少个已经完成但没有被清理的Application。这就相当于一个FIFO队列,一旦超过了这个阈值,最早的Application就会被从这个队列中清除。

在ApplicationMasterLauncher的内部,有一个线程池,用于启动ApplicationMaster。它不仅会为新提交的Application启动ApplicationMaster,也会为那些失败的ApplicationAttempt重启一个ApplicationMaster。在一个Application完成后,它也负责告诉NodeManager来清理ApplicationMaster.

由于ApplicationMaster是不被信任的,它可能会申请任意多的Container,而并不分配,只是恶意的导致ResourceManager无法为新的Application分配Container.

所以,这个组件如果在一段时间之内,不能从NodeManager上,接收到ResourceManager已经分配的Container的heartbeat,就会认为这个Container已经挂掉了,并告诉ResourceManager让这个Container过期。

另外,一个容器的过期时间,也会被编码到和Container相对应的ContainerToken中,并一同发送给NodeManager。这样可以防止NodeManager来加载已经过期的容器。

但是,我们也可以看到,除非NodeManager和ResourceManager的时钟同步,否则这会导致一些我们不希望看到的错误。

和安全相关的组件

ContainerToken中维护着和这个Container相关的一些信息,并且被加密过。由于ApplicationMaster是不被信任的,所以我们需要ContainerToken,让NodeManager来验证这个Container是否确实是ResourceManager分配的,以及是否确实就是在这个NodeManager上运行的,等其他信息。

ContainerToken中,包含下面的信息:

ApplicationMaster可以通过本地化过的文件,'ApplicationConstants.CONTAINER_TOKEN_FILE_ENV_NAME',来获得这个Token文件。

ResourceManager总结

从上面的组件我们可以看到,ResourceManager的主要功能,就是分配ApplicationMaster,为ApplicationMaster分配容器,以及监控NodeManager的状态和集群中的可用资源。

NodeManager

NodeManager的任务包括:

在NodeManager注册到ResourceManager之后,它就会不间断的向ResourceManager发送heartbeat,如果ResourceManager有需要它执行的指令,就作为响应发送给它。

在ResourceManager收到NodeManager的heartbeat并处理完之后,对应这个NodeManager的Container,就会在下一次ApplicationMaster给ResourceManager发送heartbeat时,作为ResourceManager的响应,发送给ApplicationMaster.

在NodeManager加载一个Container之前,它需要本地化需要的Resource,包括数据文件,可执行文件,shell script等。这些Resource可能有能够在不同用户之间共享的Resource,有能够在相同用户不同Application之间共享的Resource,以及只能够被这一个Container使用的Resource.

NodeManager也可以在ResourceManager的指示下,杀掉Container。当处于下面的几种场景中时,NodeManager就可能Kill掉一个Container:

当一个Container完成时,NodeManager会清除它在本地存储的数据。当一个Application完成时,NodeManager会删除全部跟它相关的Container的数据。

NodeManager组件

在NodeManager注册完以后,在后面的通讯中,NodeStatusUpdater会告诉ResourceManager,NodeManager上的Container的状态,NodeManager上刚启动的Container,以及完成的Container.

ResourceManager也可以通过和这个组件的沟通,让NodeManager Kill掉一个Container。

当一个Application结束后,ResourceManager会告诉NodeManager来清理掉和Application相关的一切信息。并且会将每个Application的日志聚合到一个文件系统中。

其中RPC Server接收来自ApplicationMaster的请求,来运行或者停止一个Container。

ResourceLocalizationService会将Resource进行本地化,根据不同的Resource visibility - PUBLIC, APPLICATION, PRIVATE,会执行不同的本地化操作。

ContainersLauncher内部维护了一个线程池,来准备并且启动Container。当RPC Server接收到一个Clean up的请求,或者NodeStatusUpdater接收到一个Clean up的请求,它也会对Container进行 Clean up的操作。每个启动或者Clean up的操作,都是在一个线程中执行的,并且直到对应的操作完成才会返回。所以,不同Container之间是相互不影响的。

AuxiliaryServices是一些可插拔的Services。有的时候,NodeManager上的现有的Services不能完全满足我们的需求,比如,我们上面提到过,在一个Container完成之后,NodeManager会清理掉它占用的本地资源。在MapReduce中,这明显不合理,Mapper的输出还要传送给Reducer呢。

所以,YARN通过这样一种方式,让我们可以自己配制一些Service,来增强它的功能。

AuxiliaryServices,会在Application第一次启动Container,每个Container的启动和结束,以及Application完成时收到通知,并执行其中预定义的操作。

在一个Container启动时,AuxiliaryServices相关的信息,会返回给ApplicationMaster。这样,ApplicationMaster就能够接收AuxliaryServices中我们希望它知道的信息。比如,在MapReduce中,会通过这种方式获得ShuffleHandler的端口信息。

ContainersMonitor会监控Container占用的资源是否超过了给它配制的最大值,如果是,则将它Kill掉。

Log Handler负责决定是在这个NodeManager保存Container的日志,还是将它压缩打包之后,上传到某个文件系统上。

ApplicationMaster

一旦ApplicationMaster成功启动后,那么它就要做这些事情:

当ApplicationMaster注册到ResourceManager时,它可以向ResourceManager发送IPC address或者Web URL. 而ResourceManager作为响应,会返回给它一些它需要的信息,比如,ResourceManager能够接受的最小以及最大的Resource的限制, Application的ACL等。

在ApplicationMaster成功注册到ResourceManager之后,它就需要不间断地向ResourceManager发送心跳信息,保证ResourceManager知道它还存活。

如果ApplicationMaster积累了足够多的ResourceRequest,或者已经到了再次发送heartbeat的时候了,那么它就会通过heartbeat信息,将这些ResourceRequest发送给ResourceManager.

ResourceRequest是ApplicationMaster发送给ResourceManager的用于请求Resource的一个数据结构。它包含了:

当ApplicationMaster从ResourceManager中取到Container之后,它就开始在NodeManager上真正启动这个Container。

ApplicationMaster会构造一个ContainerLaunchContext对象,这个对象中,包含了运行一个Container所需要的全部信息,比如,ResourceManager分配给这个容器的Resource,一些token,Container要执行的命令,环境变量等。它既可以一个一个地启动这些Container,也可以一次把它们全部启动起来。

在NodeManager接收到AppliationMaster的请求之后,它会发送一个列表作为响应,里面包含了已经成功启动的Container,以及失败的Container,以及NodeManager上全部AuxiliaryService相关的元数据。

ApplicationMaster也可以告诉NodeManager来停止Contaienr,通过发送一个StopContainersRequest,这个请求包含了要停止的Container的ID。NodeManager会回复一个StopContainersResponse,告诉ApplicationMaster哪些Container已经成功停止。

此外,处理Container失败的情况,是Application的责任. YARN只是将集群中的资源暴露给Application。

所以,ApplicationMaster需要观察Container的状态,exit code,以及一些诊断信息。例如,当MapReduce ApplicationMaster知道一个Container失败之后,它会不断重试这个Map或者Reducer,通过跟ResourceManager沟通分配Container。直到达到了指定的最大重试阈值。

此外,ApplicationMaster也需要在它自己发生错误并恢复后,恢复之前的Applicaiton的信息。当一个ApplicationMaster发生错误之后,ResourceManager只会启动一个新的ApplicationAttempt,并为其分配一个ApplicationMaster。这个新的ApplicationMaster应该能够自动检索旧的ApplicationMaster中的Application的信息。当然,如果从头再运行一个也是可以的。但是毕竟性能可能低一些。

在MapReduce中,ApplicationMaster会恢复已经完成的Task,而那些在ApplicationMaster恢复过程中仍在运行的Task,则会被Kill掉。

当一个ApplicationMaster已经完成了它的全部工作之后,它应该向ResourceManager发送一个FinishApplicationRequest的请求,来取消注册。在这个请求中,ApplicationMaster可以告诉ResourceManager一个IPC以及Web URL,让Client能够检索这个Application的历史信息。

总结

在这篇文章中,我们详细阐述了ResourceManager,NodeManager以及ApplicationMaster的作用。

上一篇 下一篇

猜你喜欢

热点阅读