1.YARN 基本架构
YARN 总体上一个 Master/slave 架构,在整个资源调度框架中,包含几个关键角色:ResourceManager 、NodeManager 、ApplicationMaster 、Container。其基本架构图如下:
由上图可知,Client 负责任务的提交,NodeManager 通过心跳机制向 ResoureceManager 汇报自大数据培训己负责的节点资源,ApplicationMaster 负责向 RM 申请资源,并且监控所有的任务运行状态。
ResourceManager(RM):RM 是一个全局的资源管理器,负责整个系统的资源管理和分配。它主要由 Scheduler 和 ApplicationManager 组成。
- Scheduler:调度器根据容量、队列等限制条件(例如:每个队列分配一定的资源,最多执行一定数量的作业等),将系统中的资源分配给各个正在运行的应用程序,且只负责调度 Containers。它不会监控或者跟踪应用的执行状态,也不会重试失败的任务。此外,该调度器是一个可插拔组件,User 可以根据自己的需求自定义调度器。YARN 提供了两种常见的调度器:公平调度器(Fair Scheduler)和容量调度器(Capacity Scheduler)。
- Application Manager:它负责系统中所有应用程序的管理工作。接收客户端的请求;为每个 Application 分配第一个 Container 用来运行 ApplicationMaster;监控 ApplicationMaster 并在任务失败时重启 ApplicationMaster 运行的 Container。
NodeManager: NodeManager 主要管理集群中每个节点的资源和任务,一方面它会通过心跳机制定时的向 RM 汇报本节点上的资源使用情况、每个 Container 的运行状态以及健康状态;另一方面,接收并处理 ApplicationMaster 的 Container 启动/停止请求。
ApplicationMaster(AM): 用户提交的每个 Application 都包含一个 AM,其运行在 Container 中,其主要功能包括:
- 与 RM 调度器协商以获取资源(用Container表示);
- 与 NM 通信以启动/停止任务;
- 监控所有任务的运行状态,并在任务失败时,重新为任务申请资源以重启任务。
Container: 它是 YARN 中的资源抽象,它封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等。
值得说明的是:它是一个动态资源划分单位,根据应用程序的需求动态生成。此外,RM 只负责告诉 AM 有哪些 Container 可用,AM 还需要与 NM 通信,以获得具体的 Container!
2.YARN 通信协议
2.1什么是 RPC?
RPC(Remote Procedure Call)即远程过程调用,简单的理解是一个节点请求另一个节点提供的服务。举个例子:有两台服务器 1 和 2 ,某一个应用部署在 1 服务器上,想要调用 2 服务器上应用提供的函数/方法,但是又不在同一个内存空间,所以不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。
RPC 通常采用 client/server 模型。请求方为 client端,应答方则是 Server。其调用流程如下图所示。主要分为以下几个步骤:
- client 端程序本地调用系统产生的 Stub 程序;
- client stub 程序将函数调用信息按照网络通信模块的要求封装成消息包,并交给通信模块(也就是sockets)发送到远程服务端;
- 远程服务端收到此消息后,将消息发送给相应的的 server stub 程序;
- server stub 程序拆封消息,并调用服务器上对应的函数;
- 被调函数(server function)执行,并将结果返回给 server stub程序;
- server stub 程序将此结果封装成消息,通过网络通信模块逐级地传给 client。
值得注意的是:在上述流程中,无论是 client,还是 server 端都涉及到 stub 程序,可以把它看成一个代理程序。它使得远程函数调用看起来跟本地调用一样,对用户完全透明。
2.2YARN 包含哪些通信协议?
YARN 通过 RPC 协议实现各个组件之间的通信,在任意两个需要相互通信的组件之间仅有一个 RPC 协议。在通信双方中,一方是 Client端,另一方是 Server端,且 Client 端总是主动连接 Server ,YARN 各个组件之间的 C/S 关系如图所示,其中箭头指向的组件是 RPC Server,而箭头尾部的组件是 RPC Client。
从上图可知,YARN 的通信协议主要由 5 大协议组成:
- JobClient 与 RM 之间 --- ApplicationClientProtocol: JobClient 通过该 RPC 协议提交应用程序、查询应用程序的状态。
- Admin 与 RM 之间 --- ResourceManagerAdministrationProtocol:Admin 通过这个协议更新系统的配置文件。
- AM 与 RM 之间 --- ApplicationMasterProtocol:AM 通过该协议向 RM 之间注册和注销自己,并进行资源请求。
- AM 与 NM 之间 --- ContainerManagermentProtocol:AM 通过该 RPC 协议与 NM 通信,请求启动/停止任务,并获取各个 Container 的使用状态。
- NM 与 RM 之间 --- ResourceTracker : NM 通过这个协议向 RM 注册,通过发送心跳信息汇报当前节点的资源使用情况、container 运行情况以及自己的健康状态。
以上各个组件之间,有且仅有一个 RPC 协议,有了这些协议,才使得这些组件能够互相通信,发挥出分布式集群的优点。
2.3RPC 实战案例
说一千,道一万,都不如写一个简易的 Demo 学的更明白。通过这个简易的 Demo,模拟 RPC 的客户端、服务端、通信协议三者是如何工作的。
需求:RPC 接口协议定义一个创建文件夹的方法,服务端实现该接口协议并创建 RPC 服务;客户端通过获取服务代理并调用服务端的创建文件夹的方法!
代码实现:
创建 RPC 协议
创建 RPC 服务端
创建 RPC 客户端
运行结果
- 启动服务端,可以看到控制台输出:server start work!
- 启动客户端,可以看到客户端控制台输出:client,服务端控制台输出:server,create path。
通过上述简易 Demo 可知:通信协议其实就是接口规范,客户端和服务端都需要遵守这个规范;客户端调用通信协议方法,方法最终在服务端执行,并对用户程序是完全透明的。
3.YARN 工作调度流程
当用户向 YARN 集群中提交一个 MR 程序后,可以分成 2 个大的阶段:
- 首先,启动 ApplicationMaster
- 其次,ApplicationMaster 创建应用程序,并为该应用程序申请资源,监控它的运行状态,直到运行完成。
为了更好的理解 YARN 的工作流程,下面以 MapReduce 计算框架为例,通过提交一个 WordCount 应用程序,来全面解析 YARN 的工作机制。其运行流程如图所示:
在 YARN 提交一个作业,其整个过程可以分为三大阶段:作业提交、作业初始化、任务分配与运行。
3.1作业提交
- 用户在 client 端提交并运行一个应用程序,其中包括启动 AM 的命令、ApplicationMaster 程序和用户程序;
- YarnRunner 向 RM 申请一个 Application,同时 RM 返回该应用程序的资源路径和 Application_id 给 YarnRunner;
- client 将运行该程序所需要的资源(切片信息、配置文件、jar包)提交到 HDFS 上指定的路径;
- 资源提交完毕,向 RM 申请运行 ApplicationMaster;
3.2作业初始化
- RM 将 client (可能会有多个)请求初始化成一个 Task,将该任务放入调度器中;
- RM 与某一个空闲的 NM 通信,并下发该任务,该 NM 为该应用程序分配第一个 Container,在这个 Container 中启动 ApplicationMaster;
- Container 从 HDFS 上拷贝资源到本地;
3.3任务分配与运行
- AM 先向 RM 注册,这样用户便可以直接通过 RM 查看应用程序的运行状态,之后,AM 采用轮询的方式通过 RPC 协议向 RM 申请和领取资源,运行 MapTask ;
- RM 将 MapTask 任务分配给另外几个 NodeManager,NodeManager 创建容器;
- AM 与收到任务的 NM 通信,并发送程序启动脚本,要求其启动任务;
- ApplicationMaster 等待所有的 MapTask 运行完毕后(假设形成0、1两个分区),向 RM 申请 Container 运行 ReduceTask;
- Reduce 向 Map 获取属于自己分区的数据进行计算;(如:Reduce Task 0 获取所有节点上 0 分区的数据)
- 程序计算结束后,ApplicationMaster 向 ResourceManager 注销自己。
4.总结
本文主要阐述了 YARN 的基本架构与组成,各组件间的通信协议,YARN 的工作调度流程。
了解 YARN 的基本架构,可以帮助我们在开发工作中更好的定位问题,而通信协议规范了各个组件间的接口规范。在全作业提交流程中,揭开了各个组件间是如何协作完成一次任务运行的。