揭秘Hadoop Yarn:分布式集群的“超级操作系统”

75 阅读8分钟

在大数据处理的早期,Hadoop 1.x 时代的 MapReduce 不仅负责计算,还负责资源管理,这种“既当裁判又当运动员”的模式导致了扩展性差、只能支持单一计算框架等痛点。Yarn(Yet Another Resource Negotiator)的出现彻底改变了这一局面,它将资源管理与计算框架解耦,让 Hadoop 演变成了一个大数据的“分布式操作系统”。

Hadoop 相关知识与文章参考:

1. Yarn 概述及核心架构

Yarn 的核心设计理念是解耦。它负责整个集群的资源管理(CPU、内存等),而具体的计算逻辑(如 MapReduce、Spark、Flink)则作为应用程序运行在 Yarn 之上。

Yarn 的架构主要由以下四大核心组件构成,它们协同工作以维持集群的高效运转:

1.1. ResourceManager (RM):集群的大管家

RM 是全局的主节点,负责整个系统的资源管理和分配。它内部包含两个关键组件:

  • 调度器(Scheduler): 纯粹的“资源分配器”。它根据容量队列、公平性等策略,将资源分配给各个应用程序。它不监控任务的运行状态,只负责“分地盘”。
  • 应用程序管理器(ApplicationsManager): 负责接收客户端提交的应用,为应用启动第一个容器(ApplicationMaster),并在 ApplicationMaster 失败时负责重启。

1.2. NodeManager (NM):干活的打工节点

NM 运行在集群的每一个从节点上。它负责管理单个节点上的资源(如定期向 RM 发送心跳汇报资源使用情况),并根据指令启动和监控容器(Container)。它还负责隔离性检查,确保容器不会超额使用资源。

1.3. ApplicationMaster (AM):应用专属的管家

每个提交到 Yarn 的应用程序(如一个 Spark 任务)都会有一个专属的 AM。它的作用是“看住”自己的应用:

  • 向 RM 申请资源(Container)。
  • 与 NM 通信,在分配到的 Container 中启动具体的任务(Task)。
  • 监控任务的运行状态和进度。

1.4. Container:资源的抽象封装

Container 是 Yarn 对资源的抽象,它封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等。应用程序只有在获得 Container 后,才能在其中运行具体的任务。

2. Yarn任务提交流程

3. Yarn常用命令

在日常运维和开发中,我们经常需要通过命令行与 Yarn 交互。以下是高频使用的命令。

简单记录一下,平常应该是使用不到命令,一般通过 Web 界面即可。

3.1. 查看任务

查看所有任务。

yarn application -list

根据 application 状态过滤。

yarn application -list -appStates FINISHED

3.2. Kill任务

yarn application -kill application_16728830***_0001

3.3. 查看日志

查询 application 日志。

yarn logs -applicationId application_16728830***_0001

查询 Container 日志。

yarn logs -applicationId application_16728830***_0001 -containerId container_16728830***_0001_01_000001

3.4. 查看尝试任务的任务

查看 application 尝试运行的任务列表。

yarn applicationattempt -list application_16728830***_0001

查询 application attemp 状态。

yarn applicationattempt -status appattempt_16728830***_0001_000001

3.5. yarn container查看容器

列出所有 container。

yarn container -list appattempt_16728830***_0001_000001

查询 container 状态。

yarn container -status container_16728830***_0001_01_000001

意:只有任务在跑着的时候,才可以看到 container 状态。

3.6. yarn node状态

yarn node -list -all

3.7. yarn rmadmin更新配置

yarn rmadmin -refreshQueues

3.8. yarn queue查看队列

yarn queue -status default

4. Yarn资源调度器

4.1. 概述

调度器是 ResourceManager 的核心组件,决定了资源如何分配给不同的队列和应用。Yarn 主要支持三种调度器:FIFO、Capacity Scheduler 和 Fair Scheduler。

Hadoop3.1.3 默认使用的是 Capacity Scheduler。

在 yarn-default.xml 中。

<property>
  <description>The class to use as the resource scheduler.</description>
  <name>yarn.resourcemanager.scheduler.class</name>
  <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>

4.2. 资源调度器

4.2.1. FIFO 调度器

FIFO 先进先出队列,按照到达时间排序,先到达先服务。

如果有一个任务很慢,就会拖累后面的任务;

4.2.2. 容量调度器

Capacity Scheduler 容量调度器。

  1. 支持多队列,每个队列可配置一定的资源,每个队列采用 FIFO 调度策略。
  2. 为了防止同一个用户的作业独占队列中的资源,该调度器会对同一用户提交的作业所占资源量进行限定。
  3. 首先,计算每个队列中正在运行的任务数与其应该分得的计算资源之间的比值,选择一个该比值最小的队列——最闲的。
  4. 其次,按照作业优先级和提交时间顺序,同时考虑用户资源量限制和内存限制对队列内任务排序。
  5. 三个队列同时按照任务的先后顺序依次执行,比如,job11、job21和job31分别排在队列最前面,先运行,也是并行运行。

4.2.3. 公平调度器

Fair Scheduler 公平调度器。

同队列所有任务共享资源,在时间尺度上获取公平的资源。

  1. 支持多队列多作业,每个队列可以单独配置;
  2. 同一队列的作业,按照其优先级分享整个队列的资源,并发执行;
  3. 每个作业可以设置最小资源值,调度器会保证获得其以上的资源;

4.3. 容量调度器多队列提交案例

在 Yarn 默认的配置下,容量调度器只有一条 Default 队列。

  1. 添加新的队列

例如,我们需要创建一条新队列,然后跑 hive 任务

在 capacity-scheduler.xml 配置文件中,可以配置多条队列,并降低 default 队列的资源占比;

<!-- 添加队列 -->
<property>
  <name>yarn.scheduler.capacity.root.queues</name>
  <value>default,hive</value>
  <description>
    The queues at the this level (root is the root queue).
  </description>
</property>

<!-- 配置default队列比例 -->
<property>
  <name>yarn.scheduler.capacity.root.default.capacity</name>
  <value>40</value>
</property>
  1. 为新队列 hive 添加属性
<!-- 队列目标资源百分比,所有队列相加必须等于100-->
<property>
  <name>yarn.scheduler.capacity.root.hive.capacity</name>
  <value>60</value>
</property>

<!-- 队列最大资源百分比-->
<property>
  <name>yarn.scheduler.capacity.root.hive.maximum-capacity</name>
  <value>100</value>
</property>

<!-- 单用户可用队列资源占比-->
<property>
  <name>yarn.scheduler.capacity.root.hive.user-limit-factor</name>
  <value>1</value>
</property>

<!-- 队列状态(RUNNING或STOPPING)-->
<property>
  <name>yarn.scheduler.capacity.root.hive.state</name>
  <value>RUNNING</value>
</property>

<!-- 队列允许哪些用户提交(*代表所有用户)-->
<property>
  <name>yarn.scheduler.capacity.root.hive.acl_submit_applications</name>
  <value>*</value>
</property>

<!-- 队列允许哪些用户管理(*代表所有用户)-->
<property>
  <name>yarn.scheduler.capacity.root.hive.acl_administer_queue</name>
  <value>*</value>
</property>
  1. 向 hive 队列提交任务

MapReduce 任务默认提交到 default 队列中,所以如果想要提交到其他队列时,需要在 Driver 驱动类中进行声明

Configuration configuration = new Configuration();
// 让当前任务在"hive"队列中运行
configuration.set("mapred.job.queue.name", "hive");

//1. 获取一个Job实例
Job job = Job.getInstance(configuration);

5. 任务的推测执行

5.1. 作业完成时间取决于最慢任务完成时间

一个作业由若干个 Map 任务和 Reduce 任务构成。因硬件老化、软件Bug等,某些任务可能运行非常慢。

思考:系统中有99%的Map任务都完成了,只有少数几个Map老是进度很慢,完不成,怎么办?

5.2. 推测执行机制

发现拖后腿的任务,比如某个任务运行速度远慢于任务平均速度。为拖后腿任务启动一个备份任务,同时运行。谁先运行完,则采用谁的结果。

5.3. 推测执行的前提条件

  1. 每个 Task 只能有一个备份任务;
  2. 当前 Job 已经完成的 Task 必须不小于 5%;
  3. 开启推测执行参数设置。mapred-site.xml 文件中默认是打开的
<property>
  <name>mapreduce.map.speculative</name>
  <value>true</value>
  <description>If true, then multiple instances of some map tasks may be executed in parallel.</description>
</property>

<property>
  <name>mapreduce.reduce.speculative</name>
  <value>true</value>
  <description>If true, then multiple instances of some reduce tasks may be executed in parallel.</description>
</property>

5.4. 不能使用推测执行机制的情况

  1. 任务存在严重的负载倾斜(开启后依旧会负载倾斜,不会有效果);
  2. 特殊任务,比如任务向数据库中写数据(如果开启了推测执行,会往数据库中插入重复的数据);

6. 总结

Yarn 作为 Hadoop 生态系统的“资源操作系统”,通过其精巧的解耦设计,成功将资源管理与任务调度分离,彻底解决了 Hadoop 1.x 时代的扩展性瓶颈。它不仅通过 ResourceManager、NodeManager、ApplicationMaster 和 Container 四大组件的协同,实现了集群资源的高效、统一管理,还凭借容量调度器(Capacity Scheduler)等灵活的调度策略,满足了多租户、多业务场景下的资源隔离与共享需求。而推测执行机制的引入,则像一个智能的“加速器”,有效规避了慢节点带来的性能拖累。

掌握 Yarn 的核心架构、常用命令、调度策略及优化手段,是每一位大数据工程师构建稳定、高效数据平台的基石。理解它,就掌握了驾驭大规模分布式计算的钥匙。