前面已经简单介绍过 Hadoop 是什么。没看过的可以看下面的文章。
Hadoop 简介
通过上一篇文章的学习,我们知道 Hadoop 主要的组成部分有如下四个:
- Hadoop Common:支持其他 Hadoop 模块的通用程序。
- Hadoop 分布式文件系统 (HDFS):一种分布式文件系统,可提供对应用程序数据的高吞吐量访问。
- Hadoop YARN:作业调度和集群资源管理的框架。
- Hadoop MapReduce:基于 YARN 的系统,用于并行处理大型数据集。
由于 Spark 相比于 MapReduce 的一系列优点,所以很多公司将 Spark 作为 Hive 的底层计算引擎,而资源调度器仍然使用 Yarn。所以今天先学习 Yarn 资源调度器,为后面学习 Spark 打下铺垫。
1.Yarn 架构
主要由 ResourceManager、NodeManager、ApplicationMaster 和 Container 构成。
ResourceManager(RM):
- 处理客户端请求;
- 监控 NodeManager;
- 启动和监控 ApplicationMaster;
- 资源的分配与调度。
NodeManager(NM):
- 管理单个节点上的资源;
- 处理来自 ResourceManager 的命令;
- 处理来自 ApplicationMaster 的命令。
ApplicationMaster(AM):
- 负责数据的切分;
- 为应用程序申请资源并分配给内部任务;
- 任务的监控与容错。
Container:
- 资源的抽象,封装了内存、CPU、磁盘、网络等。
2.Yarn 工作机制
- MR 程序提交到客户端所在的节点。
- YarnRunner 向 ResourceManager 申请一个 Application。
- RM 将该应用程序的资源路径返回给 YarnRunner。
- 该程序将运行所需资源提交到 HDFS 上。
- 程序资源提交完毕后,申请运行 MRAppMaster。
- RM 将用户的请求初始化成一个 Task。
- 其中一个 NodeManager 领取到 Task 任务。
- 该 NodeManager 创建容器 Container,并产生 MRAppMaster。
- Container 从 HDFS 上拷贝资源到本地。
- MRAppMaster 向 RM 申请运行 MapTask 资源。
- RM 将运行 MapTask 任务分配给另外两个 NodeManager,另两个 NodeManager 分别领取任务并创建容器。
- MR 向两个接收到任务的 NodeManager 发送程序启动脚本
- 这两个 NodeManager 分别启动 MapTask,MapTask 对数据分区排序。
- MRAppMaster 等待所有 MapTask 运行完毕后,向 RM 申请容器,运行 ReduceTask。
- ReduceTask 向 MapTask 获取相应分区的数据。
- 程序运行完毕后,MR 会向 RM 申请注销自己。
3.作业提交流程
作业提交:
- 第1步:Client 调用 job.waitForCompletion 方法,向整个集群提交 MapReduce 作业。
- 第2步:Client 向 RM 申请一个作业 id。
- 第3步:RM 给 Client 返回该 job 资源的提交路径和作业 id。
- 第4步:Client 提交 jar 包、切片信息和配置文件到指定的资源提交路径。
- 第5步:Client 提交完资源后,向 RM 申请运行 MRAppMaster。
作业初始化:
- 第6步:当 RM 收到 Client 的请求后,将该 job 添加到容量调度器中。
- 第7步:某一个空闲的 NM 领取到该 job。
- 第8步:该 NM 创建 Container,并产生 MRAppMaster。
- 第9步:下载 Client 提交的资源到本地。
任务分配:
- 第10步:MRAppMaster 向 RM 申请运行多个 MapTask 任务资源。
- 第11步:RM 将运行 MapTask 任务分配给另外两个 NodeManager,另两个 NodeManager 分别领取任务并创建容器。
任务运行:
- 第12步:MR 向两个接收到任务的 NodeManager 发送程序启动脚本,这两个 NodeManager 分别启动 MapTask,MapTask 对数据分区排序。
- 第13步:MrAppMaste r等待所有 MapTask 运行完毕后,向 RM 申请容器,运行 ReduceTask。
- 第14步:ReduceTask 向 MapTask 获取相应分区的数据。
- 第15步:程序运行完毕后,MR 会向 RM 申请注销自己。
进度和状态更新:
- YARN 中的任务将其进度和状态(包括 counter)返回给应用管理器, 客户端每秒(通过 mapreduce.client.progressmonitor.pollinterval 设置)向应用管理器请求进度更新, 展示给用户。
作业完成:
- 除了向应用管理器请求作业进度外, 客户端每 5 秒都会通过调用 waitForCompletion() 来检查作业是否完成。时间间隔可以通过 mapreduce.client.completion.pollinterval 来设置。作业完成之后, 应用管理器和 Container 会清理工作状态。作业的信息会被作业历史服务器存储以备之后用户核查。
4.资源调度器
Hadoop 作业调度器主要有三种:FIFO、Capacity Scheduler 和 Fair Scheduler。
- 先进先出调度器(FIFO):按到达时间,先到先服务。
- 容量调度器(Capacity Scheduler):
- 多个队列,每个队列采用 FIFO;
- 每个队列设置资源最低保证和资源使用上限;
- 如果一个队列中的资源有剩余,可以暂时共享给那些需要资源的队列;
- 一旦该队列有新的应用程序提交,则其他队列借调的资源会归还给该队列;
- 支持多用户共享集群和多应用程序同时运行;
- 每个队列有严格的 ACL 列表规定它的访问用户,每个用户可指定哪些用户允许查看自己应用程序的运行状态或者控制应用程序(比如杀死应用程序);
- 管理员可指定队列管理员和集群系统管理员;
- 管理员可根据需要动态修改各种配置参数,以实现在线集群管理。
- 公平调度器(Fair Scheduler):让所有的作业随着时间的推移,都能平均地获取等同的共享资源,它能让小的任务在合理的时间完成,同时不会让需要长时间运行的耗费大量资源的任务挨饿。
- 多个队列,以队列为单位划分资源;
- 在每个队列中,Fair Scheduler 可选择按照 FIFO、Fair 或 DRF 策略为应用程序分配资源;
- Fair 策略:默认情况下,每个队列内部采用 Fair 策略方式分配资源(即队列中有 n 个应用程序同时运行,则每个应用程序可得到 1/n 的资源);
- DRF(Dominant Resource Fairness)策略:不同应用进行不同资源(CPU、内存、带宽等)的需求不同,按照一个不同比例的分配(例如A是内存主导 2% CPU, 3% 内存,B是 CPU 主导 6% CPU, 1% 内存)。 当某个队列中有剩余资源时,调度器会将这些资源共享给其他队列,该队列中有新的应用程序提交时,调度器要为它回收资源,采用了先等待再强制回收的策略。提高小应用程序响应时间。由于采用了最大最小公平算法,小作业可以快速获取资源并运行完成。