Skip to content

YARN — 资源调度

什么是 YARN

YARN(Yet Another Resource Negotiator)是 Hadoop 2.0 引入的集群资源管理系统,将资源管理与作业调度分离,使 Hadoop 集群不再局限于 MapReduce,可以运行 Spark、Flink、Tez 等多种计算框架。

核心设计目标

  • 资源管理与计算框架解耦
  • 多租户资源隔离
  • 高可用(ResourceManager HA)
  • 细粒度资源分配(CPU + 内存)

架构设计

┌─────────────────────────────────────────────────────────────┐
│                      YARN 集群                               │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐  │
│  │              ResourceManager(RM)                    │  │
│  │  - 全局资源管理                                       │  │
│  │  - 接收应用提交                                       │  │
│  │  - 调度器(Scheduler)                               │  │
│  │  - ApplicationManager                               │  │
│  └──────────────────────────┬───────────────────────────┘  │
│                             │                               │
│  ┌──────────────────────────▼───────────────────────────┐  │
│  │                  NodeManager(NM)集群                │  │
│  │  ┌─────────────────┐    ┌─────────────────┐         │  │
│  │  │  NodeManager 1  │    │  NodeManager 2  │         │  │
│  │  │  Container      │    │  Container      │         │  │
│  │  │  [AM]           │    │  [Task]         │         │  │
│  │  │  Container      │    │  Container      │         │  │
│  │  │  [Task]         │    │  [Task]         │         │  │
│  │  └─────────────────┘    └─────────────────┘         │  │
│  └──────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

核心组件

  • ResourceManager(RM):全局资源管理,负责资源分配和调度
  • NodeManager(NM):节点资源管理,启动和监控 Container
  • ApplicationMaster(AM):每个应用的管理者,向 RM 申请资源
  • Container:资源分配单位(CPU + 内存),在 NM 上运行

作业提交流程

1. 客户端提交应用(spark-submit / flink run)


2. ResourceManager 分配 Container,启动 ApplicationMaster


3. ApplicationMaster 向 RM 注册,申请资源(Container)


4. RM 根据调度策略分配 Container(在哪个 NM 上)


5. AM 与对应 NM 通信,启动 Container(运行 Task)


6. Task 执行,AM 监控进度


7. 应用完成,AM 向 RM 注销,释放资源

调度器

FIFO 调度器

最简单,先进先出,不支持多队列,不适合生产环境。

Capacity 调度器(默认)

xml
<!-- capacity-scheduler.xml -->
<configuration>
  <!-- 定义队列 -->
  <property>
    <name>yarn.scheduler.capacity.root.queues</name>
    <value>default,production,development</value>
  </property>

  <!-- 各队列容量(百分比,总和 = 100) -->
  <property>
    <name>yarn.scheduler.capacity.root.default.capacity</name>
    <value>20</value>
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.production.capacity</name>
    <value>60</value>
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.development.capacity</name>
    <value>20</value>
  </property>

  <!-- 最大容量(可以借用空闲资源) -->
  <property>
    <name>yarn.scheduler.capacity.root.production.maximum-capacity</name>
    <value>80</value>
  </property>

  <!-- 用户限制(单用户最多使用队列的 50%) -->
  <property>
    <name>yarn.scheduler.capacity.root.production.user-limit-factor</name>
    <value>0.5</value>
  </property>
</configuration>

Fair 调度器

公平调度,所有应用平均分配资源,支持抢占:

xml
<!-- fair-scheduler.xml -->
<allocations>
  <queue name="production">
    <minResources>10000 mb, 10 vcores</minResources>
    <maxResources>90000 mb, 90 vcores</maxResources>
    <weight>3</weight>
    <schedulingPolicy>fair</schedulingPolicy>
  </queue>

  <queue name="development">
    <minResources>5000 mb, 5 vcores</minResources>
    <weight>1</weight>
  </queue>

  <!-- 抢占配置 -->
  <defaultMinSharePreemptionTimeout>300</defaultMinSharePreemptionTimeout>
  <fairSharePreemptionTimeout>600</fairSharePreemptionTimeout>
</allocations>

提交作业到指定队列

bash
# Spark 提交到 production 队列
spark-submit \
  --master yarn \
  --queue production \
  --driver-memory 4g \
  --executor-memory 8g \
  --executor-cores 4 \
  --num-executors 20 \
  myapp.jar

# MapReduce 提交到指定队列
hadoop jar myapp.jar MyJob \
  -Dmapreduce.job.queuename=production \
  input output

资源配置

xml
<!-- yarn-site.xml -->

<!-- NodeManager 可用内存(根据机器内存设置,留 20% 给 OS) -->
<property>
  <name>yarn.nodemanager.resource.memory-mb</name>
  <value>24576</value>  <!-- 24GB -->
</property>

<!-- NodeManager 可用 CPU 核数 -->
<property>
  <name>yarn.nodemanager.resource.cpu-vcores</name>
  <value>16</value>
</property>

<!-- Container 最小内存 -->
<property>
  <name>yarn.scheduler.minimum-allocation-mb</name>
  <value>1024</value>
</property>

<!-- Container 最大内存 -->
<property>
  <name>yarn.scheduler.maximum-allocation-mb</name>
  <value>16384</value>
</property>

<!-- 开启 cgroup 资源隔离(CPU 隔离) -->
<property>
  <name>yarn.nodemanager.container-executor.class</name>
  <value>org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor</value>
</property>

常用命令

bash
# 查看集群资源
yarn node -list
yarn node -status <node-id>

# 查看队列信息
yarn queue -status default
yarn queue -status production

# 查看应用列表
yarn application -list
yarn application -list -appStates RUNNING
yarn application -list -appTypes SPARK

# 查看应用详情
yarn application -status <application-id>

# 终止应用
yarn application -kill <application-id>

# 查看应用日志
yarn logs -applicationId <application-id>
yarn logs -applicationId <application-id> -containerId <container-id>

# 查看 ResourceManager 状态
yarn rmadmin -getServiceState rm1
yarn rmadmin -getServiceState rm2

# 刷新队列配置(不重启)
yarn rmadmin -refreshQueues

# 查看节点标签
yarn node -list -showDetails

YARN HA 配置

xml
<!-- yarn-site.xml -->
<property>
  <name>yarn.resourcemanager.ha.enabled</name>
  <value>true</value>
</property>
<property>
  <name>yarn.resourcemanager.cluster-id</name>
  <value>yarn-cluster</value>
</property>
<property>
  <name>yarn.resourcemanager.ha.rm-ids</name>
  <value>rm1,rm2</value>
</property>
<property>
  <name>yarn.resourcemanager.hostname.rm1</name>
  <value>rm-host1</value>
</property>
<property>
  <name>yarn.resourcemanager.hostname.rm2</name>
  <value>rm-host2</value>
</property>
<property>
  <name>yarn.resourcemanager.zk-address</name>
  <value>zk1:2181,zk2:2181,zk3:2181</value>
</property>
<!-- 自动故障切换 -->
<property>
  <name>yarn.resourcemanager.ha.automatic-failover.enabled</name>
  <value>true</value>
</property>

节点标签(Node Labels)

节点标签用于将不同硬件配置的节点分组,实现精细化调度:

bash
# 添加节点标签
yarn rmadmin -addToClusterNodeLabels "gpu,ssd,highmem"

# 给节点打标签
yarn rmadmin -replaceLabelsOnNode "node1:gpu node2:gpu node3:ssd"

# 队列绑定标签
# capacity-scheduler.xml
# yarn.scheduler.capacity.root.gpu-queue.accessible-node-labels=gpu
# yarn.scheduler.capacity.root.gpu-queue.accessible-node-labels.gpu.capacity=100
bash
# 提交作业到 GPU 节点
spark-submit \
  --master yarn \
  --queue gpu-queue \
  --conf spark.yarn.am.nodeLabelExpression=gpu \
  --conf spark.executor.nodeLabelExpression=gpu \
  myapp.jar

本站内容由 褚成志 整理编写,仅供学习参考