第四章:Hadoop YARN 资源管理框架 (Yet Another Resource Negotiator) 第四章:Hadoop YARN 资源管理框架 (Yet Another Resource Negotiator) Hadoop YARN(Yet Another Resource Negotiator)是Apache Hadoop 2.0及更高版本中的核心组件,它彻底改变了Hadoop的资源管理和作业调度方式。在Hadoop 1.0时代,MapReduce框架既负责作业处理逻辑,又负责资源管理,这导致了扩展性瓶颈和对MapReduce范式的过度依赖。
Hadoop YARN(Yet Another Resource Negotiator)是Apache Hadoop 2.0及更高版本中的核心组件,它彻底改变了Hadoop的资源管理和作业调度方式。在Hadoop 1.0时代,MapReduce框架既负责作业处理逻辑,又负责资源管理,这导致了扩展性瓶颈和对MapReduce范式的过度依赖。YARN的引入,旨在解决这些问题,它将资源管理和作业调度功能从MapReduce中分离出来,形成一个通用的资源管理平台,允许各种数据处理框架(如MapReduce, Spark, Tez, Flink等)运行在同一个Hadoop集群之上,从而大大提高了集群的资源利用率和灵活性。
YARN的设计目标是构建一个可扩展、可靠、灵活的集群资源管理系统。其核心思想是将资源管理的功能从JobTracker(Hadoop 1.0中的作业调度和资源管理中心)中分离出来,并分解为两个主要的守护进程:ResourceManager (RM) 和 NodeManager (NM)。此外,YARN还引入了 ApplicationMaster (AM) 的概念,用于管理应用程序的生命周期和资源请求。
以下是一个使用 Mermaid 绘制的 YARN 架构图:
主要组件及其职责:
ResourceManager (RM): 集群的资源管理器,是整个YARN集群的中心。它负责集群资源的分配和管理,包括CPU、内存、网络带宽等。ResourceManager 主要由两个主要组件构成:
Scheduler (调度器): 负责资源调度,根据应用程序的资源需求和集群的资源状况,将资源分配给应用程序。YARN支持多种调度器,如FIFO Scheduler, Capacity Scheduler, Fair Scheduler,以满足不同场景的需求。调度器本身不负责监控或跟踪应用程序的状态,也不负责重启失败的任务。
ApplicationManager (应用程序管理器): 负责管理集群中运行的所有应用程序。它接受客户端提交的作业,启动和监控ApplicationMaster实例,并在ApplicationMaster失败时重启它。
NodeManager (NM): 运行在集群中每个节点上的代理,负责管理单个节点上的资源和容器。NodeManager 主要负责以下职责:
管理节点上的可用资源 (CPU, 内存, 磁盘, 网络)。
启动和监控容器 (Containers)。
向ResourceManager汇报节点资源使用情况和容器状态。
定期向ResourceManager发送心跳信息,保持节点活性。
ApplicationMaster (AM): 每个应用程序的管理者,运行在容器中。ApplicationMaster 负责应用程序的生命周期管理,包括:
向ResourceManager协商应用程序所需的资源 (Containers)。
与NodeManager协同工作,启动、监控和管理应用程序的任务 (Tasks)。
跟踪应用程序的进度和状态。
在任务失败时进行容错处理。
完成应用程序后,释放占用的资源。
Container (容器): YARN 中的资源分配单元,代表着一组资源的集合,如CPU核数、内存大小等。应用程序的任务运行在容器中。Container 是动态分配的,由ResourceManager根据应用程序的需求和集群资源状况进行分配。NodeManager 负责容器的生命周期管理,包括创建、启动、监控和销毁容器。
Client (客户端): 用户提交应用程序的接口。客户端负责:
向ResourceManager提交应用程序。
获取应用程序的状态和运行信息。
与ApplicationMaster直接通信(可选,例如获取更细粒度的应用状态)。
当客户端提交一个应用程序到YARN集群时,YARN会经历一系列步骤来启动和运行该应用程序。以下是YARN应用程序的典型工作流程:
客户端提交应用程序 (Job Submission): 客户端将应用程序的提交请求发送给ResourceManager。提交请求通常包括应用程序的描述信息、启动命令、资源需求以及应用程序的JAR包等。
ResourceManager 接收请求并分配 Container (Container Allocation for AM): ResourceManager 收到客户端的应用程序提交请求后,ApplicationManager 组件会负责处理该请求。ResourceManager 的调度器会根据集群资源状况,选择一个合适的 NodeManager,并在该 NodeManager 上分配一个 Container 用于启动 ApplicationMaster。
NodeManager 启动 ApplicationMaster (AM Launch): 被选中的 NodeManager 接收到 ResourceManager 的指令后,会在分配的 Container 中启动 ApplicationMaster 进程。ApplicationMaster 进程通常会加载应用程序相关的代码和配置。
ApplicationMaster 向 ResourceManager 注册 (AM Registration): ApplicationMaster 启动后,会向 ResourceManager 注册自己,以便 ResourceManager 管理和监控该应用程序。注册信息包括 ApplicationMaster 的地址、心跳地址等。
ApplicationMaster 向 ResourceManager 请求资源 (Resource Request): ApplicationMaster 根据应用程序的需求,向 ResourceManager 发送资源请求。资源请求包括所需的 Container 数量、每个 Container 的资源规格 (CPU, 内存等) 以及 Container 的位置偏好 (可选)。
ResourceManager 调度和分配资源 (Resource Allocation): ResourceManager 的调度器根据 ApplicationMaster 的资源请求和集群当前的资源状况,进行资源调度和分配。调度器会选择合适的 NodeManager,并在其上分配 Container 给 ApplicationMaster。
NodeManager 启动 Container (Container Launch for Tasks): NodeManager 接收到 ResourceManager 的 Container 分配指令后,会在分配的 Container 中启动应用程序的任务进程 (Tasks)。这些任务进程可以是 MapReduce 的 TaskTracker,Spark 的 Executor 等。
ApplicationMaster 监控和管理任务 (Task Execution and Monitoring): ApplicationMaster 负责监控和管理应用程序的任务。它会跟踪任务的执行进度、状态,并在任务失败时进行容错处理,例如重新调度失败的任务。任务执行过程中,Container 会向 ApplicationMaster 汇报任务状态。
应用程序完成 (Application Completion): 当应用程序的所有任务都执行完成后,ApplicationMaster 会向 ResourceManager 注销自己,并释放占用的资源。ResourceManager 会通知客户端应用程序已完成。
以下是一个使用 Mermaid 绘制的 YARN 应用程序工作流程图:
YARN 的调度器负责根据应用程序的资源需求和集群的资源状况,有效地分配集群资源。YARN 支持多种调度器,常见的有三种:FIFO Scheduler, Capacity Scheduler, Fair Scheduler。
FIFO Scheduler (先进先出调度器): 最简单的调度器,将应用程序放入一个队列中,按照提交顺序依次执行。先提交的应用程序会先获得资源,后提交的应用程序需要等待前面应用程序执行完成才能获得资源。FIFO Scheduler 易于理解和配置,但缺点是长作业会阻塞短作业,导致集群资源利用率不高,不适合多用户和多应用的生产环境。
Capacity Scheduler (容量调度器): 允许多个组织共享同一个 Hadoop 集群,每个组织被分配一部分集群容量。容量调度器支持分层队列,可以为不同的队列分配不同的资源容量和优先级。在每个队列内部,资源可以采用 FIFO 或 Fair 调度策略。容量调度器可以保证每个组织都能够获得一定的资源,避免资源饥饿,同时提高集群的资源利用率。
Fair Scheduler (公平调度器): 旨在为所有应用程序公平地分配资源。Fair Scheduler 会动态地调整每个应用程序获得的资源,使得所有应用程序在一段时间内都能获得大致相等的资源。当只有一个应用程序运行时,它可以使用集群的所有资源;当有多个应用程序运行时,每个应用程序都会获得集群资源的一部分。Fair Scheduler 也支持分层队列,可以对队列设置权重和资源限制,实现更灵活的资源分配策略。
调度器选择配置:
可以通过 yarn-site.xml 配置文件中的 yarn.resourcemanager.scheduler.class 属性来配置 YARN 使用的调度器。例如,配置使用 Capacity Scheduler:
<property> <name>yarn.resourcemanager.scheduler.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value> </property>
不同的调度器有不同的配置参数,例如 Capacity Scheduler 的队列配置,Fair Scheduler 的队列和池配置,这些配置都可以在相应的配置文件中进行设置。
为了演示 YARN 的实际应用,我们来看一个简单的代码实践:提交一个 MapReduce 作业到 YARN 集群。虽然我们通常使用命令行工具来提交作业,但了解其背后的配置和原理对于深入理解 YARN 至关重要。
环境准备:
确保已经安装并配置好 Hadoop YARN 集群。
编写一个简单的 MapReduce 程序,例如 WordCount。
将 MapReduce 程序打包成 JAR 文件。
配置步骤:
配置 yarn-site.xml: 该文件配置了 YARN 集群的核心参数,例如 ResourceManager 的地址、NodeManager 的配置等。确保客户端的 yarn-site.xml 文件与集群的配置一致。
配置 mapred-site.xml: 该文件配置了 MapReduce 应用程序相关的参数,例如指定 MapReduce 作业运行在 YARN 上。
<property> <name>mapreduce.framework.name</name> <value>yarn</value> </property>
配置 core-site.xml: 该文件配置了 Hadoop 的核心参数,例如 HDFS 的地址。确保客户端的 core-site.xml 文件与集群的配置一致。
提交作业 (命令行方式):
使用 hadoop jar 命令提交 MapReduce 作业到 YARN 集群。
hadoop jar <path_to_your_jar> <main_class> <input_path> <output_path>
例如,提交 WordCount 作业:
hadoop jar /path/to/wordcount.jar org.example.WordCount /input /output
代码示例 (Java API - 了解原理):
虽然通常不直接使用 Java API 提交作业,但以下代码片段展示了如何使用 Hadoop Configuration 对象配置并提交一个 MapReduce 作业。这有助于理解背后发生的配置过程。
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; public class WordCountClient { public static void main(String[] args) throws Exception { if (args.length != 2) { System.err.println("Usage: WordCountClient <input path> <output path>"); System.exit(-1); } Configuration conf = new Configuration(); // 显式指定 MapReduce 框架为 YARN (通常在 mapred-site.xml 中配置) conf.set("mapreduce.framework.name", "yarn"); Job job = Job.getInstance(conf, "Word Count"); job.setJarByClass(WordCountClient.class); // 设置主类 // 设置 Mapper 和 Reducer 类 (假设已经定义) // job.setMapperClass(WordCountMapper.class); // job.setReducerClass(WordCountReducer.class); // 设置输入输出格式 job.setInputFormatClass(TextInputFormat.class); job.setOutputFormatClass(TextOutputFormat.class); // 设置输入输出路径 FileInputFormat.setInputPaths(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); // 提交作业并等待完成 boolean success = job.waitForCompletion(true); System.exit(success ? 0 : 1); } }
代码解释:
Configuration conf = new Configuration(); 创建 Hadoop 配置对象,加载 core-site.xml, yarn-site.xml, mapred-site.xml 等配置文件。
conf.set("mapreduce.framework.name", "yarn"); 显式设置 MapReduce 框架为 YARN。虽然通常在 mapred-site.xml 中配置,但这里为了演示目的,代码中也进行了设置。
Job job = Job.getInstance(conf, "Word Count"); 创建一个 Job 实例,并设置作业名称。
job.setJarByClass(WordCountClient.class); 设置作业的 JAR 文件,YARN 会将包含该类的 JAR 文件分发到集群节点。
// job.setMapperClass(...), // job.setReducerClass(...) 设置 Mapper 和 Reducer 类 (需要根据实际的 MapReduce 程序进行设置)。
FileInputFormat.setInputPaths(...), FileOutputFormat.setOutputPath(...) 设置输入和输出路径,通常是 HDFS 路径。
job.waitForCompletion(true); 提交作业到 YARN 集群,并等待作业完成。true 参数表示打印作业进度信息。
监控作业:
作业提交后,可以通过 YARN 的 ResourceManager Web UI (通常在 http://<ResourceManager_Host>:<ResourceManager_Port>/ui2/ 访问) 监控作业的运行状态、进度、Container 使用情况等信息。
YARN 的引入为 Hadoop 带来了诸多优势,使其成为一个更加强大和通用的数据处理平台:
资源利用率提升: YARN 将资源管理和作业调度分离,允许多种计算框架共享同一个集群资源,提高了集群的整体资源利用率。
框架多样性支持: YARN 不再局限于 MapReduce 框架,可以支持多种数据处理框架,如 Spark, Tez, Flink 等,满足不同应用场景的需求。
扩展性和灵活性增强: YARN 的架构设计使其具有良好的扩展性,可以轻松扩展集群规模。同时,YARN 的调度器和资源管理策略也更加灵活,可以根据实际需求进行配置和调整。
实时性和交互性应用: YARN 的 Container 技术为实时计算和交互式应用提供了基础,使得 Hadoop 可以支持更多类型的应用场景。
资源隔离和多租户支持: YARN 的 Capacity Scheduler 和 Fair Scheduler 等调度器可以实现资源隔离和多租户支持,保证不同用户或组织之间的资源公平分配和隔离。
Hadoop YARN 作为 Hadoop 2.0 及更高版本的核心组件,是一个强大的资源管理框架,它彻底改变了 Hadoop 的架构和应用场景。通过将资源管理和作业调度分离,YARN 提高了集群的资源利用率、扩展性和灵活性,并支持多种数据处理框架,使得 Hadoop 能够应对更加复杂和多样化的数据处理需求。