YARN 概述
Yarn 是一个资源调度平台,负责为运算程序提供服务器计算资源,相当于一个分布式的操作系统平台,而 MapReduce、Spark、Flink 等运行程序则相当于运行于操作系统平台之上的应用程序。
YARN 产生的背景
Yarn 是 Hadoop2.X 版本中的一个新的特性。它的出现其实是为了解决第一代 MapReduce 编程框架的不足,提高集群环境下的资源利用率,这些资源包括了内存、磁盘、网络等等。
Hadoop2.X 版本中重新设计的这个 YARN 集群,具有更好的扩展性,可用性,可靠性,向后兼容性,以 及能支持除 MapReduce 以外的更多分布式计算框架。
在 MapReduce 1.x 时的架构图如下:
从上图可以看到,1.x 时也是 Master/Slave 这种主从结构,在集群上的表现就是一个JobTracker 和多个 TaskTracker。
- JobTracker:负责资源管理和作业调度
- TaskTracker:定期向 JobTracker 汇报本节点的健康状况、资源使用情况以及作业执行情况。还可以接收来自JobTracker的命令,例如启动任务或结束任务等。
那么,这种架构会存在哪些问题?
- 整个集群中只有一个 JobTracker,存在单点故障。
- JobTracker 节点压力大,不但要处理Client 的请求,还得处理 TaskTracker 的心跳等请求。
- 由于 JobTracker 是单节点,所以容易成为集群中的瓶颈,不易扩展。
- JobTracker 负责的事情太多,基本上所有的事情都需要跟 JobTracker 进行交互。
- 1.x 的整个集群只支持MapReduce 任务,不支持其他例如 Spark 的任务。
基于上面的种种原因,Hadoop 在 2.x 中对资源调度进行了剥离,形成了单独的组件,也就是 Yarn 。
YARN 的架构
Yarn 的架构图如下:
YARN 的基本思想是将资源管理和作业调度/监视的功能分解为单独的守护进程。它拥有一个全局 ResourceManager(RM)和每个应用程序 ApplicationMaster(AM)。应用程序可以是单个作业,也可以是作业的DAG(有向无环图,可以理解为对作业相互之间的依赖关系的一种描述)。
ResourceManager
ResourceManager 是基于应用程序对集群资源的需求进行调度的 YARN 集群主控节点,负责 协调和管理整个集群(所有 NodeManager)的资源,响应用户提交的不同类型应用程序的 解析,调度,监控等工作。ResourceManager 会为每一个 Application 启动一个 MRAppMaster, 并且 MRAppMaster 分散在各个 NodeManager 节点 它主要由两个组件构成:调度器(Scheduler)和应用程序管理器(ApplicationsManager, ASM)
ResourceManager 的职责:
- 处理客户端请求
- 启动或监控 MRAppMaster
- 监控 NodeManager
- 资源的分配与调度
NodeManager
NodeManager是每台机器框架代理,负责容器(Container)的管理,监视其资源使用情况(CPU,内存,磁盘,网络)并将其报告给 ResourceManager / Scheduler。
NodeManager 的职责:
- 管理单个节点上的资源,开启容器。
- 处理来自 ResourceManager 的命令
- 处理来自 MRAppMaster 的命令
ApplicationMaster
每个程序都对应一个 ApplicationMaster,它负责向资源调度器申请执行任务的资源容器,运行任务,监控整个任务的执行,跟踪整个任务的状态,处理任务失败以异常情况。
Container
Container 容器是一个抽象出来的逻辑资源单位。容器是由 ResourceManager Scheduler 服务 动态分配的资源构成,它包括了该节点上的一定量 CPU,内存,磁盘,网络等信息,MapReduce 程序的所有 Task 都是在一个容器里执行完成的,容器的大小是可以动态调整的。
YARN 执行流程
先上图,以 WordCount 的整个运行流程为例:
整个过程如下:
- 客户端所在的机器 执行 job.submit() ,调用 YarnRunner 去向 ResourceManager 申请提交一个 application。
- ReourceManager 返回 一个 资源提交的地址 hdfs://xxx/.staging/applicationid/ 和 applicationid。因为后续的任务需要执行这些个资源文件,到这个阶段,还不了解每个任务到底会分配到哪台机器上,干脆直接给一个都能访问到的地址,任务到谁那里,就自己去这个位置拉取需要的jar 包和 配置信息。
- YarnRunner 提交 job 所需要的 资源文件到上面的地址。
- YarnRunner 提交资源完毕,向 ResourceManager 申请启动 MrAppMaster。
- ResourceManager 收到请求,然后封装成一个 task 放入任务队列,等待 NodeManager 获取执行,此队列默认使用FIFO。
- NodeManager1 把这次任务下载到本地。
- NodeManager1 下载 job 相关的文件,并在本地地启动一个 Container 运行 MrAppMaster ,container 就是一个容器,利用的是 linux 的 cgroup ,现在市面上的虚拟化技术底层也是使用的此技术。
- MrAppMaster 根据配置信息,去跟 ResourceManager 申请运行 maptask 的容器,还是跟第 5 步一样,ReourceManager 拿到后封装成一个task 放到任务队列。
- Nodemanager 2 和 3 分别下载 上个步骤的 task 任务 ,然后在本地启动一个 container 容器。
- MrAppMaster 向 第9 步新启动的 容器发送 拷贝文件、执行 maptask 等任务的命令。maptask 执行完成后,把数据写到自己本地,容器的工作目录。
- MrAppMaster 再向 YARN 请求资源来运行 reducetask 任务。
- reducetask 向 map 端获取相应的分区数据进行处理 ,处理完成后进行输出。
- 整个 applicetion 执行完成后,MrAppMaster 向 ResourceManager 申请销毁自己。
参考资料
Apache Hadoop YARN http://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-site/YARN.html
Hadoop学习之路(二十四)YARN的资源调度 https://www.cnblogs.com/qingyunzong/p/8615096.html
分布式资源调度——YARN框架 https://blog.51cto.com/zero01/2091635