Yarn 架构设计 和 RPC 网络通信:
第一部分
1.YARN 的产生背景和架构剖析
2.YARN 核心组件功能特性分析
第二部分
3.YARN RPC 工作机制和实例解读
4.YARN RPC 网络通信框架原理剖析
5.YARN RPC 客户端和服务器端源码分析
6.YARN RPC 通信协议整理
总分两个方面
1.YARN 的架构设计剖析 和 核心功能组件剖析
2.YARN RPC 网络通信和 RPC 通信协议
- YARN 的 RPC 机制
- YARN 的集群启动
- MapReduce Flink Spark On YARN 的运行机制
- Container 的管理以及一些典型组件的工作机制
1.YARN 的产生背景和架构剖析
1.1 Haddop MRv1 不足
原 MapReduce 框架也称 MRv1,它是一个主从式的架构,主节点 JobTracker 负责集群的资源管理和处理 Client 请求,从节点 TaskTracker 负责管理资源和执行任务。不仅存在 JobTracker 的 SPOF (单点故障)问题,而且 JobTracker 的负载非常高,集群的资源管理也非常粗暴不合理
HDFS主从架构:
在当前的 Hadoop 有四大核心模块
Common
HDFS
MapResouce
Yarn
在Hadoop 1.x中,MapReduce 和 Yarn 的工作都是 MapReduce 做,直到之后,才出现了 Yarn,并把资源调度的工作接手,使得 MapReduce 只负责作为 计算框架 存在
拿 spark 举例:安装 spark 集群其中就有 spark standalone 集群,spark standalone 集群 = mapreduce 集群
当将 spark 的 master + worker 这些资源调度工作的单独提出来,就是类似 yarn 的功能,而 spark 的 api 等计算工作则还是由spark standalone来完成
更简单来说,spark standalone 和 flink standalone 集群的作用和 yarn 是一样的
集群类型 | 主节点 | 从节点 | 资源抽象 |
---|---|---|---|
MapReduce | JobTracker | TaskTracker | Slot(MapSlot、ReduceSlot) |
Yarn | ResourceManager | NodeManager | Container |
Spark | Master | Worker | 并没有明确的资源抽象 |
Flink | ClusterEntrypoint/JobManager | TaskManager | Slot |
主从节点的工作机制都是一样的,它们要完成的事情都是一样的
可见,MapReduce 拥有两个 Slot,当 MapSlot 被分配时,ReduceSlot 即使是空闲状态也不会参与计算工作,这使得集群资源利用率不高
而在 Yarn 里,两个 Slot 被抽象为一个 Container 了,这使得资源抽象部分不会被区分开,这一改动使得资源利用率大大提升
主要问题
1.单点故障,可靠性低:JobTracker 采用了 master/slave 结构,是集群事务的集中处理点,存在单点故障
在当前hadoop,我们启动了一个yarn,会启动一个主控程序,叫applicationMaster
注意:在hadoop1.x中,applicationMaster全部运行在JobTracker里面,20个JobTracker就有20个applicationMaster
如同运行spark时运行的主控程序 Driver,负责创建SparkSession/SparkContext、提交Job、将Job转换为Task,协调执行器之间的Task执行
到了 yarn 当中对这些操作进行了更改,主要动作是解放了 主节点
在 yarn 中,每个 主控程序 就不会运行到 主节点 里面去了,即不会再运行在 Resouce 中去了,而是在NodeManager中。如果存在100个applicationMaster的应用程序的话,那么它们是分布在100个NodeManager当中的
这样做集群的压力就小很多了
2.单点瓶颈,扩展性差:JobTracker 需要完成的任务太多,JobTracker 兼顾资源管理和作业控制跟踪任务,启动失败或迟缓的任务,记录任务的执行状态,维护计数器,压力大,成为系统的瓶颈
3.资源管理和任务执行强耦合:在 TaskTracker 端,用 Map/Resouce Task 作为资源的表示过于简单,没有考虑到 CPU、内存等资源情况,当把两个需要消耗大内存的 Task 调度到一起,很容易出现 OOM
4.资源利用率低:基于槽位的资源分配模型,槽位时一种粗粒度的资源划分单位,通常一个任务不会用完一个槽位的资源,hadoop1.x把资源强制划分为 Map/Reduce 两种Slot,当只有 MapTask 时,Teduce Slot 不能使用,反之亦然,任意造成资源利用不足
5.不支持多种分布式计算框架
比如 MapReduce 程序在 Spark Standalone 中不能运行
如何解决:把计算引擎拆分独立
至此开始,hadoop从1.x版本进入到了hadoop2.x版本
1.2 Hadoop YARN 架构演进
从hadoop2.x开始,hadoop的架构发生了变化:原来的 MapReduce (资源管理调度和数据处理计算)集群一分为二:MapReduce 和 YARN
-
MapReduce:仅仅是一套用来编写分布式计算应用程序的 API
-
YARN:是一个 master/slave架构的分布式集群,用来进行集群的资源管理和调度工作,提供了 job 调度规范,除了能运行 MapReduce 应用程序外,还可以支持 spark、flink 等分布式计算应用程序
这样拆分的目的,大大提高了 Hadoop 平台的通用性,逐渐演变成演变成大数据基础平台,甚至可以理解成用来解决大数据问题的分布式操作系统
在更高一个维度上,HDFS 和 YARN 联合起来,我们可以叫做是一个分布式操作系统
1.3 Hadoop YARN 概述
YARN,Yet Another Resource Negotiator,是Hadoop-2.x 版本中的一个新特性,它为了上层应用提供统一的资源管理和调度,它的引入为集群在利用率、资源统一管理和数据共享等方面带来了好处
它的出现是为了解决 MapReduce 编程框架的不足,提高资源利用率,资源包括内存、磁盘、网络、IO等,hadoop-2.x版本中重新设计了 YARN集群,具有更好的扩展性、可用性、可靠性、向后兼容性 以及 支持除了 MapRduce 以外的更多分布式计算程序
YARN的核心特性
- YARN 并不清楚用户提交的程序的运行机制,只是提供了一套资源管理和调度的规范
- YARN 只提供运算资源的调度(用户程序向 YARN 申请资源,YARN 就负责分配资源,具体的计算机执行逻辑完全由用户程序决定)
- YARN 是一个 master/slave 的主从架构,依靠 ZooKeeper 实现 HA,主节点叫做 ResourceManager,从节点叫做 NodeManager
- YARN 被设计成一个通用的资源管理和作业调度平台,Spark、Flink 等运算框架都可以整合在 YARN 上运行,只需要满足 YARN 规范的资源请求机制即可
1.4 Hdoop YARN (MRv2) 优势
YARN/MRv2 最基本的想法是将原 JobTracker 主要的资源管理和 Job 调度/监视功能分开作为两个单独的守护进程,有一个全局的 ResourceManager(RM)和每个 Application 有一个ApplicationMaster(AM),Application 相当于 MapReduce Job 或者 DAG jobs
ResourceManager 和 NodeManager(NM)组成了基本的数据计算框架
ResourceManager协调集群的资源利用,任何 Client 或者运行着的 ApplicationMaster 想要运行 Job 或者 Task 都得向 RM 申请一定的资源
ApplicationMaster 是一个框架特殊的库,对于 MapReduce 框架而言,它有自己的AM实现,用户也可以实现自己的 AM ,在运行的时候,AM 会与 NM 一起来启动和监视 Tasks
1.极大减小了 JobTracker 的资源消耗:每个应用程序的 ApplictionMaster 都分布在真个集群的所有 NodeManager中了
2.YARN 中的 ApplicationMaster 只是一个规范:用户可以把自己的分布式计算应用程序部署到 YARN 上运行,只要满足 ApplicationMaster 的规范
3.YARN 中的 Container 的资源抽象比 Slot 更合理:老版本的 Slot 分为 mapslot 和 reduceslot,不能混合使用,资源利用率低
4.借用 Zookeeper 解决 RM 的 SPOF 问题:老版本的 JobTracker 是存在 SPOF 的问题的
2.YARN 核心组件功能特性分析
YARN C/S架构
YARN 集群的三大核心组件:
-
Service:服务化思想,把很多很多工作组件都抽象成了 Service
-
事件驱动:使用AsyncDispatcher + EventHandier 组件来完成
-
状态机
只有理解了这三个核心组件,才具备理解 YARN 内部实现基础
这里采用Hadoop-3.1.3源码
2.1 YARN Client(客户端)
YARN Client 提交 Application 到 ResourceManager ,他会首先创建一个 Application 上下文件对象,并设置ApplicationMaster 必须的资源请求信息,然后提交到 ResourceManager,YARN Client 也可以与 ResourceManager 通信,获取到一个以及提交并运行的 Application 的状态信息等
YARN Client 能把 Application 提交到 ResourceManager 里,是实现了一个 ResourceManager 的一个代理,下列是验证
1.YARN Client 提交与响应请求的实现
YARN Client的实现在package org.apache.hadoop.yarn.client.api.impl,在 YarnClientImpl.java 文件里;
大概在142行
//源码
protected ApplicationClientProtocol rmClient;
//这个代码就是实现 RPC 的代理
ApplicationClientProtocol:通信协议:是 Client 和 RM 的通信协议
用户:通过 YARN 客户端提交 App 给 YARN 集群,即给ResourceManager
YarnClinet 发送 RPC 请求给 RM :通过 rmClient.submitApplication 完成提交
submitApplication 是 rmClient 的类型,具体实现也非常简单:
public SubmitApplicationResponse submitApplication(SubmitApplicationRequest request)thorws YarnException,IOException;
submitApplication只用于接受一个请求并返回一个响应,没有其他多余的操作
这次进入到SubmitApplicationResponse中查看
@Public
@Stable
public abstract class SubmitApplicationResponse{
@Private
@Unstable
public static SubmitAppcationResponse newInstance(){
SubmitApplicationResponse response = Records.newRecord(SubmitApplicationResponse.calss);
return response;
}
}
可以看到,SubmitApplicationResponse 是一个抽象类,主要业务只有一个,就是创建一个新的 SubmitApplicationResponse 实例,使用了位于 yarn.util 包内的Records,可以看出,这应该是一个工具类,SubmitApplicationResponse 调用了一个它,并将 SubmitApplicationResponse.class 的类赋给了newRecord,
newRecord 如下:
public static <T> T newRecord(Class<T> cls){
return factory.newRecordInstance(cls)
}
而 factory 则是一个接口,没有任何实现,可见SubmitApplicationResponse到此为止了
由上可见,总体是由 SubmitApplication 实现的。newRecord仅仅负责创建实例,而具体的响应内容由 SubmitApplicationResponse 完成,最终由 submitApplication 完成接收和提交用户数据的功能
以上是请求过程
响应过程:
SubmitApplicationRequest 创建实例,接收一个请求上下文(ApplicationSubmissionContext),然后使用Records创建一个实现,并将 ApplicationSubmissionContext 交给 request.setApplicationSubmissionContet中,最后返回一个request响应
@Public
@Stable
public static SubmitApplicationRequest newInstance(ApplicationSubmissionContext context){
SubmitApplicationRequest request = Records.newRecord(SubmitApplicationRequest.class);
request.setApplicationSubmissionContext(context);
return request;
}
而 setApplicationSubmissionContext 则接收一个 ApplicationSubmissionContext 类型的值
ApplicationSubmissionContext 则单纯用于实例化一个对象,设置了Id、Name、队列等一系列的属性
至此,RPC 通信提交功能基本解读完成,总的来说,就是从客户端接收处理数据的信息,然后发起请求,最后返回响应
2.客户端提交请求的过程
在 ResourceManager 必然会有一个 RPC 服务端用来提供服务: ClientRMService
ClientRMService 实际上就是一个 RPC 的Server端,这个 RPC Server 端就是给 ApplicationClientProtocol 提供通信协议去提供远程请求服务的
也就是说,最终是由 ClientRMService 来帮我们完成主节点接收到一个应用程序提交的时候的相关处理
3.YarnClient
为什么 Spark Flink 能够运行在 YARN 中?
因为 Spark Flink 的逻辑客户端的内部,有一个真真正正的 RPC 客户端 就是 : YarnClient
解释地说就是:
Spark On Yarn、Flink On Yarn 归根结底就是 Spark 、Flink 的逻辑客户端的内部,有一个完全的物理客户端,这个物理客户端就是Yarn Client,只是做了一个简单的包装
深入来说:
不管是 MapReduce 程序还是 Spark 程序还是 Flink 程序,只要提交到 Yarn 集群中去运行,那么必定底层的客户端都是 Yarn Client
可见,用于实现 YarnClient 的 YarnClientImpl 类的重要性
最终物理客户端的真正实现:YarnClientImpl,获取了 ResourceManager 中的 ApplicationClientProtocol 通信协议的一个代理对象,这个代理对象的内部就是 RPC 客户端
YarnClientImpl 是我们用于理解 xxx On Yarn 的基础
2.2 ResourceManager
主从架构思想:主节点是用来管理的,那么从节点就必然是真真正正用来干活的
管理者(主节点:做管理工作) + 工作者 ( 提供计算或者存储资源的,用来解决实际问题的)
ResourceManager 是一个全局的资源管理器,集群只有一个,存在 SPOF(单点故障) 问题,可以通过 Zookeeper 实现 HA 机制,它主要负责整个系统的资源管理和分配,响应用户提交的不同类型应用程序的解析、调度、监控等工作,启动和监控 ApplicationMaster,监控 NodeManager等
整体职责解析:
-
处理客户端请求
-
启动和监控 ApplicationMaster
-
监控NodeManager
-
负责资源的分配与调度
组成结构
在 Yarn 集群的内部几乎所有的组件的两两通讯都是基于事件驱动
类似我想让一个组件干活,事实上就是这个组件发了一个事件给另外一个组件
而 AsyncDispatcher 则是一个异步事件的中央驱动器,属于整个ResourceManager 最重要的两个部分功能之一,AsyncDispatcher 是完成功能的最重要的组件
而 ResourceScheduler 则是最重要的资源管理组件,做管理调度
六大模块:
-
第一个模块:User Service(用户接口)
-
1.ClientRMService:给普通用户提交请求的一个客户端,与客户端进行通信
-
2.AdminService:给管理员提供服务的服务端
-
3.RMWebAPP:给WebUI用户提供服务的服务端
-
-
第二个模块:State Machine(状态机):相关工作组件的具体工作由State Machine管理
-
1.RMApp:应用程序的状态机
-
2.RMAppAttempt:一个应用程序尝试一次运行时的状态机
-
3.RMContainer:每一个Container都拥有一个状态机
-
4.RMNode:每一个 NodeManager 也有一个状态机
-
-
第三个模块:Security(安全组件)
-
第四个模块:Manager Apps(应用程序管理)
-
1.ApplicationACLsManager:权限管理
-
2.RMAppManager:正儿八经的应用程序管理,管理应用程序的
-
3.ContainerAllocationExpirer:过期处理
-
-
第五个模块:Manager NMs(管理NodeManager)每一个 NodeManager 从节点上线后都要向 ResourceManager 注册
-
1.NMLiveLinessMonitor:生命周期管理器,对当前 NodeManager 做一个验活机制判断当前的 NodeManager 是死是活
-
2.NodeListManager:管理 NodeManager 的
-
3.ResourceTrackerService:这是一个 RPC 服务端,负责与 NodeManager 通信
-
-
第六个模块:Manager AMs(管理 ApplicationMaster)
- 1.ApplicationMasterLauncher:负责启动 ApplicationMaster 组件
- 2.AMLivelinessMonitor:生命周期管理器,对 ApplicationMaster 进行验活机制
- 3.ApplicationMasterService:一个 RPC 服务端,负责与 ApplicationMaster 通信
每一个 RPC 服务端都会绑定一个端口,才能对应不同的客户端
所有的这些 Service 都会经历三个步骤:
Service 实例的创建,创建好了后,放在 CompositeService 的 serviceList 这个成员变量集合中
然后遍历这个 serviceList 集合,取出每个 service 调用 serviceInit() 方法
然后遍历这个 serviceList 集合,取出每个 service 调用 serivceStart() 方法
要有一个概念:在Yarn中,所有的组件都被服务化了,变成了一个个的service
2.3 ApplicationMster
ApplicationMaster 相对于 YARN 来说,就类似 Spark 中的 Driver
总而言之,一个分布式程序在运行当中必然会分成多个 Task ,这时,管理 Task 的所属关系等就是ApplicationMaster 的工作,一个应用程序就会启动一个 ApplicationMaster ,去负责当前应用程序中的所有 Task 的运行,如:监控 Task 状态,监控 Task 的容错等等
职责解析:
每个 YARN 内部的 Application 都会启动一个 ApplicationMaster,负责向 ResourceManager 注册 Applivcation 和申请 Container
ApplicationMaster 还负责管理整个应用程序的生命周期、资源申请、阶段调度等
调度分为两层:
1.Application 和 Task
2.ResourceManager 和 Appliction
简单来讲就是,ResourceManager 管理 Application,Application 管理 Task
2.4 MRAppMaster
MRAppMaster 就是 MapReduce 的一个 Application 应用程序运行在 YARN 之上的 ApplicationMaster
简单理解就是 MRAppMster 是 MapReduce 的一个 Application 应用程序运行在 YARN 的 ApplicationMaster
更简单点理解就是 MapReduce 运行在 YARN 上启动的一个ApplicationMaster(服务化概念)
也就是 MapReduce 的 ApplicaitonMaster
Driver 就可以理解为 Spark 运行在 Standalone 集群上的 ApplicaitonManager
注意:ApplicationMaster 和 ApplicationManager 是不一样的
步骤说明:
第一步:客户端提交程序给 Resource Manager
第二步:Resource Manager 去寻找 NodeManager ,让 Node Manager 启动 Application Master
第三步:Applicaiton Master 向 Resource Manager 指定注册
第四步:注册成功后,Application Master 向 Resource Manager 申请资源
第五步:申请资源成功,那么对应的 Container 就会向 Application Master 进行汇报
第六步:如果 Application Master 检查确定申请的资源均到位后,接下来开始部署 Task
第七步:Client 可以直接联系 Application Master 以直接拿到程序的运行状态
2.5 Scheduler
帮助我们管理和调度资源的一个组件
YARN 的资源调度服务:根据应用程序需要的资源请求以及集群的资源情况,为应用程序分配对应的资源,他不会关系你拿到申请到的 Container 资源去做什么
即调度器就是一个单纯的调度器,只管分配资源,其余工作均不参与
2.6 NodeManager
R M:Resource Manager
A M:Application Master
NodeManager 是 YARN 集群中真正的资源提供者,是真正执行应用程序的容器的提供者,监控应用程序资源使用情况,并通过心跳向集群资源调度器 Resource Manager 进行汇报以更新自己的健康状态,同时监督 Container 的生命周期管理 以及每个 Container 的资源使用情况,跟踪节点健康情况,管理日志和不同应用程序用到的附属服务(auxiliary service)
职责:
管理自身资源
处理 R M 命令
处理 A M 命令
2.7 Container
Cn:Container
Flink Slot(决定每个从节点被抽象成多少个 Slot) = Yarn Container 逻辑资源管理单位 (默认每个 Cn 用多数资源
Flink On YARN 的 Session 模式:客户端发送命令给 YARN ,给你提供 Cn 启动集群(主+从节点)动态资源申请,还有 per job 模式,也有 application 模式
简单来讲就是
YARN 要运行一个 Task ,就得申请一个 Container ,申请一个 Container 后就用这个 Container 运行一个 Task
3.RPC
RPC(Remote Procedure Call) 是指 远程过程调用,也就是说两台服务器 A,B,一个应用部署在 A 服务器上,想要调用 B 服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达的数据
PRC 工作机制