YARN 资源调度与队列配置全解析
适用于:Hadoop 2.x / 3.x 中使用 YARN 的大数据平台
目标:搞清楚 YARN 如何管理资源、如何创建/划分队列、如何调优并发任务数,并给出可直接套用的
yarn-site.xml&capacity-scheduler.xml模板。
一、YARN 资源模型快速回顾
YARN(Yet Another Resource Negotiator)是 Hadoop 的资源管理和调度层,核心组件与概念:
- ResourceManager(RM):集群"大脑",负责全局资源调度与队列管理。
- NodeManager(NM):每台工作节点上的"看门人",汇报本机资源、启停 Container。
- ApplicationMaster(AM):每个应用一个 AM,负责本应用内部的任务调度(MR task / Spark executor)。
- Container:YARN 分配给应用的基本资源单位(内存 + vCores)。
YARN 主要管理两种资源:
memory-mb:内存(必选)vcores:虚拟 CPU 核数(逻辑核;在一些简单场景下可忽略)
二、YARN 的几种资源分配 / 调度方式
1. FIFO Scheduler
- 类名:
org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler - 特点:
- ✅ 先进先出,行为简单直观;
- ✅ 配置最少,适合测试环境或小集群;
- ❌ 不支持多队列、多租户资源隔离;
- ❌ 一个大任务可以长时间占用资源,小任务只能干等。
启用示例(yarn-site.xml):
xml
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler</value>
</property>
典型场景:单用户、小规模临时集群,只求简单不要隔离。
2. Capacity Scheduler(生产环境最常用)
- 类名:
org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler - 思路:按**队列容量(capacity)**划分集群资源;每个部门 / 环境一个队列,各自有保障、互不抢占。
优点:
- ✅ 原生支持多队列、多租户资源隔离;
- ✅ 每个队列有保证容量(
capacity)和最大容量(maximum-capacity),空闲资源可以在队列之间"借用"; - ✅ 支持按内存+CPU 的 DominantResourceCalculator;
- ✅ Hadoop 3.x 官方推荐,生态支持最好。
缺点:
- ❌ 配置项比较多,理解成本略高;
- ❌ 队列配置需要统一管理,不适合"随便改"。
启用示例(yarn-site.xml):
xml
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>
大多数生产集群都建议使用 CapacityScheduler,下文的模板也默认使用它。
3. Fair Scheduler(渐渐"退居二线")
- 类名:
org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler - 思路:让所有运行中的应用"公平"拿资源,避免单个大 Job 把小任务"压死"。
优点:
- ✅ 新应用能较快拿到一部分资源,延迟友好;
- ✅ 支持多队列 / Pool;
- ✅ 适合混合同批任务 & 长服务。
缺点:
- ❌ 需要额外
fair-scheduler.xml; - ❌ Hadoop 3.x 之后官方更推荐 CapacityScheduler,新版本中 FairScheduler 的维护度逐渐下降。
启用示例:
xml
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
</property>
三、ResourceCalculator:按"内存"还是"内存+CPU"算资源?
在 Capacity / Fair 调度器下,还有一个关键配置:资源计算方式(ResourceCalculator)。
1. DefaultResourceCalculator
- 类名:
org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator - 只考虑 memory,不管 vCores。
2. DominantResourceCalculator
- 类名:
org.apache.hadoop.yarn.util.resource.DominantResourceCalculator - 同时考虑 memory 与 vCores,谁更紧张按谁算"主导资源"。
对比:
| Calculator | 资源维度 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| DefaultResourceCalculator | 只看内存 | 配置简单,调度逻辑直观 | 看不到 CPU 维度的"抢占" | 小集群 / CPU 较富余的场景 |
| DominantResourceCalculator | 内存 + vCores | 综合利用内存和 CPU,更符合真实资源瓶颈 | 计算略复杂,但对用户感知不大 | 生产环境,强烈推荐 |
配置示例(CapacityScheduler):
xml
<!-- 推荐:综合考虑内存 + vCores -->
<property>
<name>yarn.scheduler.capacity.resource-calculator</name>
<value>org.apache.hadoop.yarn.util.resource.DominantResourceCalculator</value>
</property>
四、集群级资源配置(yarn-site.xml 关键参数)
假设每台节点物理配置:128G 内存 / 32 核 CPU,希望给 YARN 分配 120G / 30 核:
xml
<!-- 每个 NodeManager 可用于 YARN 的内存(MB) -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>122880</value> <!-- 120G -->
</property>
<!-- 每个 NodeManager 可用于 YARN 的 vCores 数 -->
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>30</value>
</property>
<!-- 单个 Container 最小/最大内存(MB) -->
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>1024</value> <!-- 1G -->
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>32768</value> <!-- 32G -->
</property>
<!-- 单个 Container 最小/最大 vCores -->
<property>
<name>yarn.scheduler.minimum-allocation-vcores</name>
<value>1</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-vcores</name>
<value>16</value>
</property>
这些参数决定了容器粒度 :Spark executor / MR task 的
memory和cores都不能超过这里的最大值。
五、CapacityScheduler 队列模型与关键配置
1. 队列层级与 root.queues
所有队列都在 root 根队列之下。
xml
<!-- root 下定义了三个一级队列 -->
<property>
<name>yarn.scheduler.capacity.root.queues</name>
<value>default,prod,dev</value>
</property>
这就对应:
root.defaultroot.prodroot.dev
之后所有队列相关的配置,都以 yarn.scheduler.capacity.root.<queue-name>.* 的形式出现。
2. 队列容量与最大容量(capacity / maximum-capacity)
百分比方式:
xml
<!-- default 队列保证 20% 容量 -->
<property>
<name>yarn.scheduler.capacity.root.default.capacity</name>
<value>20</value>
</property>
<!-- default 队列最多可以借到 40% -->
<property>
<name>yarn.scheduler.capacity.root.default.maximum-capacity</name>
<value>40</value>
</property>
绝对资源方式(新版本支持):
xml
<!-- 写死 default 队列的资源上限 -->
<property>
<name>yarn.scheduler.capacity.root.default.maximum-capacity</name>
<value>[memory=368640,vcores=90]</value>
</property>
两种方式二选一即可:
- 百分比:适合总资源会扩缩的集群;
- 绝对值:适合"我就 3 台机器,总资源固定"的小集群。
3. AM 资源比例:maximum-am-resource-percent
这是非常关键、也最容易被忽略的一个参数:
控制 某个队列中最多有多少资源可以被 AM(ApplicationMaster)使用。
xml
<property>
<name>yarn.scheduler.capacity.root.default.maximum-am-resource-percent</name>
<value>0.3</value> <!-- 允许 default 队列最多用 30% 资源跑 AM -->
</property>
如果这个值太小,比如 0.1,那么能同时启动的 AM 数就会受到严重限制------
典型现象就是:
集群资源很富裕,但新的任务一直停留在
ACCEPTED状态,同一时间只有 3~4 个任务处于
RUNNING。
推荐范围:0.2 ~ 0.4,视作业类型与并发需求而定。
4. 每队列最大 Application 数:maximum-applications
xml
<property>
<name>yarn.scheduler.capacity.root.default.maximum-applications</name>
<value>2000</value>
</property>
用来防止有人一口气提一句"10 万个小任务"把 RM 撞挂。
一般设一个相对大的数值即可,比如 1000 / 2000。
5. 每队列单 Application 的容器上限:maximum-allocation-*
xml
<property>
<name>yarn.scheduler.capacity.root.default.maximum-allocation-mb</name>
<value>32768</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.maximum-allocation-vcores</name>
<value>16</value>
</property>
- 如果不配置,则默认用
yarn.scheduler.maximum-allocation-*; - 可以按队列维度限制最大容器规格:
比如dev队列最多 8G / 4 核,prod队列允许 32G / 16 核。
6. 用户维度限制:user-limit-factor & minimum-user-limit-percent
xml
<property>
<name>yarn.scheduler.capacity.root.default.user-limit-factor</name>
<value>1</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.minimum-user-limit-percent</name>
<value>25</value>
</property>
大致含义:
minimum-user-limit-percent:当队列资源紧张时,每个用户至少能拿到的队列容量百分比;user-limit-factor:单用户最多可以占用的队列资源倍数(= factor × 队列 capacity)。
例子:
capacity=30,user-limit-factor=1→ 单用户最多能使用队列 30% 的资源;- 如果希望"一个用户可以吃满整个队列",可以把
user-limit-factor设置得大一些,比如 2 或 3。
7. 队列权限:谁能提交、谁能管理?
xml
<property>
<name>yarn.scheduler.capacity.root.default.acl_submit_applications</name>
<value>hadoop,user1,user2</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.acl_administer_queue</name>
<value>hadoop</value>
</property>
acl_submit_applications:允许哪些用户/组向该队列提交应用;acl_administer_queue:允许哪些用户管理该队列(包括修改配置、杀掉队列内任务等)。
8. 创建新队列的标准步骤
以新增一个 prod 队列为例(CapacityScheduler):
-
编辑
capacity-scheduler.xml:-
在
yarn.scheduler.capacity.root.queues中追加prod:xml<property> <name>yarn.scheduler.capacity.root.queues</name> <value>default,prod</value> </property> -
为
root.prod配置capacity、maximum-capacity、权限等。
-
-
在 RM 节点执行:
bashyarn rmadmin -refreshQueues # 或重启 ResourceManager -
应用侧指定队列提交:
-
Spark:
bashspark-submit ... --queue prod -
MapReduce:
bashyarn jar job.jar ... -D mapreduce.job.queuename=prod
-
六:yarn-site.xml 模板示例(CapacityScheduler + DominantResource)
下面是一份可以直接参考的 yarn-site.xml 模板,按需替换主机名和资源量即可。
xml
<?xml version="1.0"?>
<configuration>
<!-- ResourceManager 主机名 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>rm1.example.com</value>
</property>
<!-- 使用 CapacityScheduler -->
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>
<!-- NodeManager 资源上限 -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>122880</value> <!-- 120G -->
</property>
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>30</value>
</property>
<!-- Container 粒度 -->
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>1024</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>32768</value>
</property>
<property>
<name>yarn.scheduler.minimum-allocation-vcores</name>
<value>1</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-vcores</name>
<value>16</value>
</property>
<!-- 日志聚合(推荐开启) -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- 日志保留 7 天 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
</configuration>
七:capacity-scheduler.xml 模板示例
1. 单队列(root.default)模板
xml
<?xml version="1.0"?>
<configuration>
<!-- 同时考虑内存 + CPU 进行资源调度 -->
<property>
<name>yarn.scheduler.capacity.resource-calculator</name>
<value>org.apache.hadoop.yarn.util.resource.DominantResourceCalculator</value>
</property>
<!-- 集群最大 Application 数 -->
<property>
<name>yarn.scheduler.capacity.maximum-applications</name>
<value>10000</value>
</property>
<!-- 全局 AM 资源比例:最多使用 30% 集群资源跑 AM -->
<property>
<name>yarn.scheduler.capacity.maximum-am-resource-percent</name>
<value>0.3</value>
</property>
<!-- root 下只有一个 default 队列 -->
<property>
<name>yarn.scheduler.capacity.root.queues</name>
<value>default</value>
</property>
<!-- default 队列容量:100% -->
<property>
<name>yarn.scheduler.capacity.root.default.capacity</name>
<value>100</value>
</property>
<!-- default 队列最大容量:100% -->
<property>
<name>yarn.scheduler.capacity.root.default.maximum-capacity</name>
<value>100</value>
</property>
<!-- default 队列的 AM 资源比例(可覆盖全局,或与全局保持一致) -->
<property>
<name>yarn.scheduler.capacity.root.default.maximum-am-resource-percent</name>
<value>0.3</value>
</property>
<!-- default 队列中允许的最大应用数 -->
<property>
<name>yarn.scheduler.capacity.root.default.maximum-applications</name>
<value>2000</value>
</property>
<!-- default 队列中单个 Container 的上限 -->
<property>
<name>yarn.scheduler.capacity.root.default.maximum-allocation-mb</name>
<value>32768</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.maximum-allocation-vcores</name>
<value>16</value>
</property>
<!-- 用户限制 -->
<property>
<name>yarn.scheduler.capacity.root.default.user-limit-factor</name>
<value>1</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.minimum-user-limit-percent</name>
<value>50</value>
</property>
<!-- 队列状态 -->
<property>
<name>yarn.scheduler.capacity.root.default.state</name>
<value>RUNNING</value>
</property>
<!-- 队列权限配置 -->
<property>
<name>yarn.scheduler.capacity.root.default.acl_submit_applications</name>
<value>*</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.acl_administer_queue</name>
<value>hadoop</value>
</property>
</configuration>
2. 多队列(default / prod / dev)模板
xml
<?xml version="1.0"?>
<configuration>
<!-- 使用 DominantResourceCalculator -->
<property>
<name>yarn.scheduler.capacity.resource-calculator</name>
<value>org.apache.hadoop.yarn.util.resource.DominantResourceCalculator</value>
</property>
<!-- 集群最大 Application 数 -->
<property>
<name>yarn.scheduler.capacity.maximum-applications</name>
<value>10000</value>
</property>
<!-- 全局 AM 资源比例:30% -->
<property>
<name>yarn.scheduler.capacity.maximum-am-resource-percent</name>
<value>0.3</value>
</property>
<!-- root 下有三个队列:default / prod / dev -->
<property>
<name>yarn.scheduler.capacity.root.queues</name>
<value>default,prod,dev</value>
</property>
<!-- default:公共队列,容量 20%,最大 40% -->
<property>
<name>yarn.scheduler.capacity.root.default.capacity</name>
<value>20</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.maximum-capacity</name>
<value>40</value>
</property>
<!-- prod:生产队列,容量 60%,最大 100% -->
<property>
<name>yarn.scheduler.capacity.root.prod.capacity</name>
<value>60</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.prod.maximum-capacity</name>
<value>100</value>
</property>
<!-- dev:开发队列,容量 20%,最大 40% -->
<property>
<name>yarn.scheduler.capacity.root.dev.capacity</name>
<value>20</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.dev.maximum-capacity</name>
<value>40</value>
</property>
<!-- 可以按队列继续配置 AM 比例 / ACL / 用户限制,这里省略 -->
</configuration>
八、小结:YARN 资源调优的几个核心关注点
- 先定集群资源边界 :
yarn.nodemanager.resource.memory-mb、cpu-vcores要和机器实际配置匹配。 - 再定容器粒度 :
minimum/maximum-allocation-*决定了 executor / task 能申请到的资源上限。 - 选择合适调度器与 ResourceCalculator:生产环境强烈推荐 CapacityScheduler + DominantResourceCalculator。
- 合理划分队列与容量 :根据组织结构(部门、环境)设计
root.<queue>树形结构。 - 尤其注意 AM 资源比例 :
maximum-am-resource-percent决定了"最多能同时跑多少个 Job",默认 0.1 容易踩坑。 - 用命令行排查队列与资源使用情况 :
yarn queue -listyarn queue -status <queue>yarn application -list -appStates RUNNING,ACCEPTED
把这些搞清楚以后,你在排查问题时,就能很快判断:
"是单个 Job 配置太大吃光资源,
还是队列 / AM 限制太严导致并发上不去。"