1. YARN介绍
- 广义上的Hadoop:泛指Hadoop的生态圈,包括Hdfs、YARN、Hive、HBase、Flume、Sqoop等。
- 狭义上的Hadoop:指Apache顶级开源项目,包括Hadoop-common、Hadoop-Hdfs、Hadoop-YARN、Hadoop-MapReduce。
- Hadoop的前世今生——Hadoop最早起源于Nutch。Nutch的设计目标是构建一个大型的全网搜索引擎,包括网页抓取、索引、查询等功能,但随着网页数量多增加,遇到了严重的可扩展性问题——如何解决数十亿网页的存储和索引问题。
- Apache Hadoop YARN(Yet Another Resource Negotiator)是Hadoop的子项目,为分离Hadoop2.0资源管理和计算组件而引入
- YARN具有足够的通用性,可以支持其它的分布式计算模式
2. YARN角色联系
YARN是经典的主从(master/slave)架构
- YARN服务由多个ResourceManager(RM)和多个NodeManager(NM)构成
- ResourceManager为主节点(master)
- NodeManager为从节点(slave)
- Container是YARN资源的抽象
- ApplicationMaster可以理解为特殊的Container,一个应用有一个ApplicationMaster,其管理该应用的所有Container
3. YARN内部架构
3.1 ResourceManager
ResourceManager是YARN中master角色,内部架构图如下:
- 用户交互模块:ResourceManager分别针对普通用户、管理员和Web提供了三种对外服务,具体实现分别对应ClientRMService、AdminService和WebApp
- ClientRMService 为普通用户提供的服务,它处理来自客户端各种RPC请求,比如提交应用程序、终止应用程序、获取应用程序运行状态等
- AdminService ResourceManager为管理员提供了一套独立的服务接口,以防止大量的普通用户请求使管理员发送的管理命令饿死,管理员可通过这些接口管理集群,比如动态更新节点列表、更新ACL列表、更新队列信息等
- WebApp 为了更加友好地展示集群资源使用情况和应用程序运行状态等信息,YARN对外提供了一个WEB界面,这一部分是YARN仿照Haml开发的一个轻量级嵌入式Web框架
- NM管理模块:该模块主要涉及以下组件 :
- NMLivelinessMonitor 监控NM是否活着,如果一个NodeManager在一定时间内未汇报心跳信息,则认为它死掉了,需将其从集群中移除
- NodesListManager 维护正常节点和异常节点列表,管理exclude(类似于黑名单)和include(类似于白名单)节点列表,这两个列表均是在配置文件中设置的,可以动态加载
- ResourceTrackerService 处理来自NodeManager的请求,主要包括注册和心跳两种请求,其中,注册时NodeManager启动时发生的行为,请求包中包含节点ID、可用的资源上限等信息;而心跳时周期性行为,包含各个Container运行状态,运行的Application列表、节点资源状况等信息,作为请求的应答,ResourceTrackerService可为NodeManager返回待释放的Container列表、Application列表等信息
- AM管理模块:该模块主要涉及以下组件 :
- AMLivelinessMonitor 监控AM是否活着,如果一个ApplicationMaster在一定时间内未汇报心跳信息,则认为它死掉了,它上面所有正在运行的Container将被置为失败状态,而AM本身会被重新分配到另外一个节点上执行
- ApplicationMasterLauncher 与某个NodeManager通信,要求它为某个应用程序启动ApplicationMaster
- ApplicationMasterService 处理来自ApplicationMaster的请求,主要包括注册和心跳两种请求,其中,注册是ApplicationMaster启动时发生的行为,注册请求包中包含ApplicationMaster启动节点,对外RPC端口号和trackingURL等信息;而心跳而是周期性行为,汇报信息包含所需资源描述、待释放的Container列表、黑名单列表等,而AMS则为之返回新分配的Container、失败的Container、待抢占的Container列表等信息
- Application管理模块:该模块主要涉及以下组件 :
- ApplicationACLsManager 管理应用程序访问权限,包含两部分权限 :查看权限和修改权限。查看权限主要用于查看应用程序基本信息,而修改权限则主要用于修改应用程序优先级、杀死应用程序等
- RMAppManager 管理应用程序的启动和关闭
- ContainerAllocationExpirer 当AM收到RM新分配的一个Container后,必须在一定的时间内在对应的NM上启动该Container,否则RM将强制回收该Container,而一个已经分配的Container是否该被回收则是由ContainerAllocationExpirer决定和执行的
- 状态机管理模块:ResourceManager使用有限状态机维护有状态对象的生命周期,状态机的引入使得YARN设计架构更加清晰。ResourceManager共维护了四类状态机,分别是RMApp、RMAppAttempt、RMContainer和RMNode
- RMApp RMApp维护了一个应用程序的整个运行周期,包括从启动到运行结束整个过程。由于一个Application的生命周期可能会启动多个Application运行实例,因此可认为,RMApp维护的是同一个Application启动的所有运行实例的生命周期
- RMAppAttempt 一个应用程序可能启动多个实例,即一个实例运行失败后,可能再次启动一个重新运行,而每次启动称为一个运行尝试,用“RMAppAttempt”描述,RMAppAttempt维护了一次运行尝试的整个生命周期
- RMContainer RMContainer维护了一个Container的运行周期,包括从创建到运行结束整个过程。RM将资源封装成Container发送给应用程序的ApplicationMaster,而ApplicationMaster则会在Container描述的运行环境中启动任务,因此,从这个层面上讲,Container和任务的生命周期是一致的
- RMNode RMNode维护了一个NodeManager的生命周期,包括启动到运行结束整个过程
- 安全管理模块:ResourceManager自带了非常全面的权限管理机制,主要由ClientTOAMSecretManager、ContainerTokenSecretManager、ApplicationTokenSecretManager等模块完成
- 资源分配模块:该模块主要涉及一个组件 – ResourceScheduler。ResourceScheduler是资源调度器,它按照一定的约束条件将集群中的资源分配给各个应用程序。ResourceScheduler是一个插拔式模块,YARN自带了一个批处理资源调度器 – FIFO和两个多用户调度器 – Fair Scheduler和Capacity Scheduler
3.2 NodeManager
NodeManager 是YARN中的 slave角色,内部架构图如下:
- NodeStatusUpdate:NodeStatusUpdater 是 NodeManager 与 ResourceManager 通信的唯一通道。当 NodeManager 启动是,该组件负责向 ResourceManager 注册,并汇报节点上总的可用资源。之后,该组件周期性与 ResourceManager 通信,汇报各个 Container 的状态更新,包括节点上正在运行的 Container、已经完成的 Container 等信息,同时 ResourceManager 会为之返回待清理的 Container 列表、待清理的应用程序列表、诊断信息、各种 Token 等信息。
- Container管理模块:ContainerManager 是 NodeManager 中最核心的组件之一,它由多个子组件组成,每个子组件负责一部分功能,协同管理运行在该节点上的所有 Container,各个子组件如下:
- RPC Server:该 RPC Server 实现了 ContainerManagementProtocol 协议,是 ApplicationMaster 与 NodeManager 通信的唯一通道。ContainerManager 从各个 ApplicationMaster 上接收 RPC 请求以启动新的 Container 或者停止正在运行的 Container。需要注意的是,任何 Container 操作均会经 ContainerTokenSecretManager 合法性验证,以防止 ApplicationMaster 伪造启动或停止 Container 的命令。
- ContainersMonitor:ContainersMonitor 负责监控 Container 的资源使用量,为了实现资源隔离和公平共享,ResourceManager 为每个 Container 分配了一定量的资源。而 ContainersMonitor 周期性探测它在运行过程中的资源利用量,一旦发生 Container 超出了它的允许使用份额上线,就向 Container 发送信号将其杀掉,这可以避免资源密集型的 Container 影响同节点上其他正在运行的 Container。
- ResourceLocalizationService:负责 Container 所需资源的本地化,它能够按照描述从 HDFS 上下载 Container 所需的文件资源,并尽量将它们分摊到各个磁盘上以防止出现热点访问。此外,它会为下载的文件添加访问控制限制,并为之施加合适的磁盘空间使用份额。
- ContianersLauncher:维护了一个线程池以并行完成 Container 相关操作,比如启动或者杀死 Container,其中启动 Container 请求是由 ApplicationMaster 发起的,而杀死 Container 请求则可能来自 ApplicationMaster 或者 ResourceManager。
- AuxService:NodeManager 允许用户通过配置附属服务的方式扩展自己的功能,这使得每个节点可以定制一些特定框架的服务。附属服务需要在 NodeManager 启动之前配置好,并由 NodeManager 统一启动与关闭。
- LogHandler:一个可插拔组件,用户可通过它控制 Container 日志的保存方式,即是写到本地磁盘上还是将其打包后上传到一个文件系统中。
- ContainerEventDispatcher:Container 事件调度器,负责将 ContainerEvent 类型的事件调度给对应 Container 的状态机 ContainerImpl。
- ApplicationEventDispatcher:Application 事件调度器,负责将 ApplicationEvent 类型的事件调度给对应 Application 的状态机 ApplicationImpl。
- ContainerExecutor:ContainerExecutor 可与底层操作系统交互,安全存放 Container 需要的文件和目录,进而以一种安全的方式启动和清除 Container 对应的进程。目前 YARN 提供了 DefaultContainerExecutor、LinuxContainerExecutor 和 DockerContainerExecutor 三种实现。
- NodeHealthCheckerService:NodeHealthCheckerService 通过周期性地运行一个自定义脚本(由组件 NodeHealthScriptRunner 完成)和向磁盘写文件(由服务 LocalDirsHandlerService 完成)检查节点的健康状况,并将之通过 NodeStatusUpdater 传递给 ResourceManager。一旦 ResourceManager 发现一个节点处于不健康状态,则会将它加入黑名单,此后不再为它分配资源,直到再次转为健康状态。需要注意的是,节点被加入黑名单时,正在运行的 Container 仍会正常运行,不会被杀死。
- DeletionService:NodeManager 将文件删除功能服务化,即提供一个专门的文件删除服务,异步删除失效文件,这样可避免删除文件带来的性能开销。
- Security:安全模块是 NodeManager 中的一个重要模块,它包含两部分,分别是 ApplicationACLsManager 和 ContainerTokenSecretManager,ApplicationACLsManager 确保访问 NodeManager 的用户是合法的,ContainerTokenSecretManager 确保用户请求的资源被 ResourceManager 授权过。具体如下:
- ApplicationACLsManager:NodeManager 需要为所有面向用户的 API 提供安全检查,如在 Web UI 上只能将 Container 日志显示给授权用户。该组件为每个应用程序维护了一个 ACL 列表,一旦收到类似请求后会利用该列表对其进行验证。
- ContainerTokenSecretManager:检查收到的各种访问请求的合法性,确保这些请求操作已被 ResourceManager 授权。
- WebServer:通过 Web 界面向用户展示该节点上所有应用程序运行状态、Container 列表、节点健康状况和 Container 产生的日志等信息
3.3 Container
- Container 是 YARN 中的资源抽象
- YARN以Container为单位分配资源
- 它封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络、GPU、FPGA等
- 当 AM 向 RM 申请资源时,RM 为 AM 返回的资源便是用 Container 表示的
- YARN 会为每个任务至少分配一个 Container,且该任务只能使用该 Container 中指定数量的资源。
- Container 和集群NodeManager节点的关系是:
- 一个NodeManager节点可运行多个 Container
- 但一个 Container 不会跨节点。
- 任何一个 job 或 application 必须运行在一个或多个 Container 中
- 在 YARN 框架中,ResourceManager 只负责告诉 ApplicationMaster 哪些 Container 可以用
- ApplicationMaster 还需要去找 NodeManager 请求分配具体的 Container。
- 需要注意的是
- Container 是一个动态资源划分单位,是根据应用程序的需求动态生成的
- 目前为止(Hadoop3.0),YARN 支持 CPU 、内存、GPU、FPGA四种资源,且使用了轻量级资源隔离机制 Cgroups 进行资源隔离。
- 功能:
- 对task环境的抽象;
- 描述一系列信息;
- 任务运行资源的集合(cpu、内存、io等);
- 任务运行环境
3.4 *ApplicationMaster
- 功能:
- 获得数据分片;
- 为应用程序申请资源并进一步分配给内部任务(TASK);
- 任务监控与容错;
- 负责协调来自ResourceManager的资源,并通过NodeManager监视容器的执行和资源使用情况。
- ApplicationMaster 与 ResourceManager 之间的通信
- 是整个 YARN 应用从提交到运行的最核心部分,是 YARN 对整个集群进行动态资源管理的根本步骤
- ApplicationMaster周期性的向resourcemanager发送心跳,让RM确认ApplicationMaster的健康
- YARN 的动态性,就是来源于多个Application 的 ApplicationMaster 动态地和 ResourceManager 进行沟通,不断地申请、释放、再申请、再释放资源的过程。
4. YARN应用运行原理
4.1 YARN应用提交过程
- Application在YARN中的执行过程,整个执行过程可以总结为三步:
- 应用程序提交
- 启动应用的ApplicationMaster实例
- ApplicationMaster 实例管理应用程序的执行
- 简单提交过程为:
- 步骤1:用户将应用程序提交到 ResourceManager 上;
- 步骤2:ResourceManager为应用程序 ApplicationMaster 申请资源,并与某个 NodeManager 通信启动第一个 Container,以启动ApplicationMaster;
- 步骤3:ApplicationMaster 与 ResourceManager 注册进行通信,为内部要执行的任务申请资源,一旦得到资源后,将于 NodeManager 通信,以启动对应的 Task;
- 步骤4:所有任务运行完成后,ApplicationMaster 向 ResourceManager 注销,整个应用程序运行结束。
4.2 YARN应用生命周期
申请资源->启动ApplicationMaster->申请运行任务的container->分发Task->运行Task->Task结束->回收container->待所有container运行结束->回收ApplicationMaster->应用运行完成