1. YARN资源调度器概述
在大规模分布式计算环境中,资源调度器是集群管理的核心组件。作为Hadoop生态系统中的关键角色,YARN(Yet Another Resource Negotiator)资源调度器负责将集群的计算资源(CPU、内存等)高效、公平地分配给各种应用程序。不同于早期的Hadoop版本中JobTracker既做资源管理又做作业调度的架构,YARN通过将这两项职责分离,显著提升了集群的资源利用率和扩展性。
在实际生产环境中,我观察到资源调度器的选择直接影响着集群的吞吐量、响应时间和多租户隔离能力。一个配置得当的调度器可以让集群资源利用率提升30%以上,同时保证关键业务应用的SLA。接下来,我将深入解析YARN调度器的三种主要类型及其适用场景。
2. YARN调度器类型详解
2.1 FIFO调度器
FIFO(First In First Out)是最简单的调度器实现,它按照作业提交的顺序依次分配资源。这种调度器将所有应用放入一个默认队列,不考虑应用优先级或资源需求差异。
注意:FIFO调度器虽然实现简单,但在生产环境中几乎不会使用,因为它无法满足多租户和资源隔离的基本需求。
主要特点:
- 无队列概念,所有应用共享default队列
- 严格按提交时间顺序分配资源
- 不支持资源预留和抢占
- 可能导致小作业被大作业阻塞
2.2 Fair调度器
Fair调度器是Cloudera发行版的默认选择,它引入了队列概念和公平共享原则。我在CDH环境中使用该调度器时,发现它对多租户场景的支持相当完善。
核心特性包括:
- 多级队列树形结构
- 基于权重的资源分配
- 弹性资源共享机制
- 支持资源预留和抢占
- ACL访问控制
典型配置示例:
<property> <name>yarn.scheduler.fair.allocation.file</name> <value>/etc/hadoop/conf/fair-scheduler.xml</value> </property> <property> <name>yarn.scheduler.fair.user-as-default-queue</name> <value>false</value> </property>2.3 Capacity调度器
Capacity调度器是目前Apache社区和主流云厂商的推荐选择,也是我在生产环境中最常使用的调度器。它不仅包含了Fair调度器的全部功能,还增加了许多高级特性。
优势对比:
| 特性 | Fair调度器 | Capacity调度器 |
|---|---|---|
| 全局资源调度 | ❌ | ✔️ |
| 节点标签(Node Labels) | ❌ | ✔️ |
| 放置约束(Placement Constraints) | ❌ | ✔️ |
| 异步调度 | 基本支持 | 多线程优化 |
3. Capacity调度器深度解析
3.1 架构设计
Capacity调度器采用模块化设计,主要包含以下核心组件:
主调度器(MainScheduler)
- 分配线程:负责资源请求匹配和节点选择
- 提交线程:验证并提交分配提案
重调度器(ReScheduler)
- 队列间抢占:保障各队列的基础资源配额
- 队列内抢占:维护应用间的公平性
节点排序管理器
- 基于资源使用率对节点排序
- 支持自定义排序策略
放置约束管理器
- 处理应用的亲和性/反亲和性需求
- 支持节点属性匹配
3.2 调度流程
全局调度模式的工作流程可分为以下几个关键阶段:
- 分区选择:在多个node label分区间轮询
- 队列选择:从root队列开始,按保障资源使用率从低到高遍历
- 应用选择:根据队列策略(FIFO/Fair)选择待调度应用
- 请求匹配:按优先级处理资源请求
- 节点筛选:基于约束条件选择候选节点
- 提案生成:创建资源分配提案
- 提案提交:最终校验并提交分配
3.3 关键配置参数
3.3.1 全局配置
<!-- 资源计算方式 --> <property> <name>yarn.scheduler.capacity.resource-calculator</name> <value>org.apache.hadoop.yarn.util.resource.DominantResourceCalculator</value> </property> <!-- 最大AM资源占比 --> <property> <name>yarn.scheduler.capacity.maximum-am-resource-percent</name> <value>0.25</value> </property>3.3.2 队列配置示例
<!-- 定义root队列的子队列 --> <property> <name>yarn.scheduler.capacity.root.queues</name> <value>prod,dev,test</value> </property> <!-- 生产队列资源配置 --> <property> <name>yarn.scheduler.capacity.root.prod.capacity</name> <value>60</value> </property> <property> <name>yarn.scheduler.capacity.root.prod.maximum-capacity</name> <value>80</value> </property> <!-- 开发队列使用Fair策略 --> <property> <name>yarn.scheduler.capacity.root.dev.ordering-policy</name> <value>fair</value> </property>4. 高级特性与应用实践
4.1 节点标签(Node Labels)
节点标签允许将集群节点划分为不同分区,实现硬件资源隔离。我在金融行业客户的生产环境中,使用该特性将GPU节点单独划分给机器学习工作负载。
配置示例:
<property> <name>yarn.node-labels.enabled</name> <value>true</value> </property> <property> <name>yarn.node-labels.fs-store.root-dir</name> <value>hdfs://namenode:8020/node-labels</value> </property>4.2 放置约束(Placement Constraints)
对于有特殊调度需求的应用,如:
- 需要分散部署的HA服务
- 需要共置的Spark executor和HDFS数据
- 需要独占节点的MPI作业
可以通过约束表达式定义调度策略:
// 反亲和性约束:同一应用的容器不部署在同一机架 PlacementConstraints.build( PlacementConstraints.targetNotIn(NODE_ATTRIBUTE, "rack"), PlacementConstraints.PlacementTargets.nodeAttribute("app-id", appId.toString()) );4.3 动态资源配置
从YARN 3.2+开始支持通过REST API动态更新队列配置,无需重启ResourceManager:
curl -X PUT -H "Content-type: application/json" \ 'http://rm-address:8088/ws/v1/cluster/scheduler-conf' \ -d '{ "global-updates": [{ "entry": [{ "key":"yarn.scheduler.capacity.root.dev.capacity", "value":"40" }] }] }'5. 性能调优经验
5.1 调度模式选择
根据集群规模选择适当的调度模式:
| 集群规模 | 推荐模式 | 配置参数 |
|---|---|---|
| <100节点 | 节点心跳驱动 | yarn.scheduler.capacity.schedule-asynchronously.enable=false |
| 100-1k节点 | 异步调度 | yarn.scheduler.capacity.schedule-asynchronously.enable=true |
| >1k节点 | 全局调度 | yarn.scheduler.capacity.multi-node-placement-enabled=true |
5.2 常见性能问题排查
调度延迟高
- 检查:yarn.resourcemanager.scheduler.monitor.interval.ms(默认3000ms)
- 调整:减小监控间隔,但会增加RM负载
资源碎片化
- 现象:集群显示有空闲资源但应用分配失败
- 解决方案:配置较小的container大小或启用资源预留
热点节点
- 监控:NodeManager的CPU/内存使用率
- 解决:启用全局调度或调整节点排序策略
5.3 最佳实践建议
队列规划原则
- 按组织架构划分一级队列
- 按应用类型划分二级队列
- 为每个队列设置合理的capacity/maximum-capacity
资源限制设置
<!-- 防止单个任务占用过多资源 --> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>16384</value> <!-- 16GB --> </property>监控指标关注
- 队列资源使用率
- 调度器操作延迟
- 容器分配成功率
- 抢占操作次数
6. 与其他技术的集成
6.1 与Kubernetes的对比
虽然Kubernetes在容器编排领域占据主导地位,但在Hadoop生态中,YARN仍然是许多大数据工作负载的首选。两者主要区别:
| 维度 | YARN | Kubernetes |
|---|---|---|
| 调度粒度 | 容器级 | Pod级 |
| 资源模型 | 静态slot | 动态request/limit |
| 生态工具 | Hadoop生态工具链 | 云原生工具链 |
| 适用场景 | 批处理、ETL作业 | 微服务、长期运行服务 |
6.2 在混合云环境中的应用
通过YARN的Federation功能,可以将多个物理集群逻辑上统一管理:
- 配置示例:
<property> <name>yarn.resourcemanager.federation.enabled</name> <value>true</value> </property> <property> <name>yarn.resourcemanager.cluster-id</name> <value>cluster1</value> </property>- 使用场景:
- 跨数据中心资源调度
- 云上云下资源统一管理
- 弹性扩展计算能力
在实际部署中,我发现Federation对跨地域网络延迟比较敏感,建议在延迟低于50ms的网络环境中使用。