1. YARN调度器概述:集群资源管理的核心引擎
在大规模分布式计算环境中,YARN(Yet Another Resource Negotiator)作为Hadoop生态系统的资源管理层,其调度器扮演着集群资源分配决策者的关键角色。就像城市交通指挥中心需要合理调度车辆通行一样,YARN调度器决定了哪些任务可以获取资源、何时获取以及获取多少资源。当前主流调度器主要分为三类:FIFO Scheduler(先进先出调度器)、Capacity Scheduler(容量调度器)和Fair Scheduler(公平调度器),每种调度器都有其独特的设计哲学和适用场景。
在实际生产环境中,我们经常遇到这样的场景:当多个团队共享集群资源时,某个团队提交的批量作业可能独占所有资源,导致其他团队的交互式查询长时间得不到响应;或者重要业务任务因为资源不足而延迟,同时测试任务却占用了过多资源。这些问题的核心就在于调度策略的选择与配置。理解不同调度器的工作原理和调优方法,对于构建高效、公平的分布式计算平台至关重要。
提示:YARN调度器的选择直接影响集群吞吐量、资源利用率和多租户公平性,需要根据业务特点和技术需求进行针对性配置
2. 三种核心调度器深度解析
2.1 FIFO Scheduler:简单直接的调度策略
FIFO调度器采用最简单的任务排队机制,就像超市的单队列收银系统,先到的顾客先获得服务。它会按照作业提交的先后顺序,依次为每个作业分配可用资源。这种调度器实现简单,不需要复杂配置,早期Hadoop版本默认采用这种策略。
其核心工作流程为:
- 新作业到达后被放入等待队列尾部
- 调度器从队列头部开始检查资源需求
- 当集群有足够资源时,立即分配给队列中的第一个作业
- 该作业完成后,再检查下一个作业的资源需求
虽然FIFO调度器在单用户场景下表现良好,但其明显缺陷在于缺乏资源共享能力。当一个大作业运行时,后续所有作业都必须等待,即使它们只需要少量资源。这会导致集群利用率低下和用户体验差。例如,一个需要100个容器的MapReduce作业会阻塞后续只需要2个容器的Hive查询,尽管集群可能还有50个空闲容器。
<!-- FIFO调度器的基本配置示例 --> <property> <name>yarn.resourcemanager.scheduler.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler</value> </property>2.2 Capacity Scheduler:企业级多租户解决方案
Capacity调度器采用"资源预留+队列划分"的设计理念,类似于机场的VIP通道和普通通道分离机制。它将集群资源划分为多个逻辑队列,每个队列被分配固定的资源比例,且可以设置最大资源使用上限。这种设计非常适合需要资源隔离的多部门共享集群场景。
关键特性包括:
- 层级队列结构:支持树形队列层级,如root.production.root.research
- 容量保证:每个队列获得预设的最小资源占比
- 弹性分配:允许队列借用其他队列的空闲资源
- 访问控制:通过ACL控制用户/组对队列的访问权限
- 资源限制:可设置队列最大资源使用上限
一个典型的生产配置可能包含以下队列:
- production(60%容量):运行关键业务作业
- research(30%容量):用于数据分析和实验
- default(10%容量):临时和小型作业
当production队列空闲时,research队列可以借用其资源,但一旦production有新作业提交,借用的资源会被逐步回收。这种灵活性既保证了各团队的基础资源需求,又提高了整体利用率。
<!-- Capacity调度器核心配置示例 --> <property> <name>yarn.scheduler.capacity.root.queues</name> <value>production,research,default</value> </property> <property> <name>yarn.scheduler.capacity.root.production.capacity</name> <value>60</value> </property>2.3 Fair Scheduler:动态平衡的资源分配策略
公平调度器采用"按需分配+动态平衡"的策略,类似于自助餐厅的食物分配机制——每个人按当前饥饿程度获取食物,系统会动态调整分配比例。它会持续监控所有运行的应用程序,并尝试为每个应用分配等量的资源(默认公平策略),或按配置的权重分配资源。
其主要特点包括:
- 动态资源分配:根据应用需求实时调整资源分配
- 最小资源保证:可为队列设置最小共享资源
- 权重控制:通过权重参数调整资源分配比例
- 延迟调度:为提高数据本地性,可适当延迟调度
- 超售处理:支持资源超售配置
公平调度器特别适合交互式查询和长期运行服务共存的场景。例如,当HBase区域服务器和Spark应用共享集群时,公平调度器可以确保两者都能获得所需资源,而不会出现一方完全饿死另一方的情况。此外,它还能自动处理用户提交的大量小作业,防止单个用户垄断集群资源。
<!-- Fair调度器基本配置示例 --> <property> <name>yarn.scheduler.fair.allocation.file</name> <value>/etc/hadoop/fair-scheduler.xml</value> </property> <property> <name>yarn.scheduler.fair.user-as-default-queue</name> <value>false</value> </property>3. 调度器对比与选型指南
3.1 三种调度器的核心差异
通过以下对比表格可以清晰看出各调度器的特点:
| 特性 | FIFO Scheduler | Capacity Scheduler | Fair Scheduler |
|---|---|---|---|
| 调度策略 | 严格先进先出 | 队列容量保证+弹性借用 | 动态平衡+最小资源保证 |
| 资源分配单位 | 整个作业 | 队列内作业 | 单个应用 |
| 多租户支持 | 不支持 | 优秀 | 良好 |
| 资源利用率 | 低 | 中到高 | 高 |
| 延迟敏感性 | 差 | 中等 | 良好 |
| 配置复杂度 | 简单 | 中等 | 复杂 |
| 典型应用场景 | 测试环境 | 企业多部门共享 | 混合负载环境 |
3.2 调度器选型决策树
根据业务需求选择合适调度器的决策流程:
是否多用户/多团队共享集群?
- 否 → 考虑FIFO(简单场景)或Fair(动态分配)
- 是 → 进入下一步
是否需要严格的资源隔离?
- 是 → 选择Capacity Scheduler
- 否 → 进入下一步
负载类型是否多样化(批处理+交互式)?
- 是 → 优先选择Fair Scheduler
- 否 → 根据其他需求选择
是否需要支持动态资源分配?
- 是 → Fair Scheduler
- 否 → Capacity Scheduler
注意:在CDH/HDP等商业发行版中,Capacity Scheduler通常是默认选项,因其在企业环境中的稳定性和可预测性更受青睐
4. 默认调度器查看与修改方法
4.1 查看当前使用的调度器
通过以下方法确定集群正在使用的调度器类型:
方法一:检查YARN ResourceManager日志
grep "Scheduler class" /var/log/hadoop-yarn/resourcemanager/*.log典型输出:
org.apache.hadoop.yarn.server.resourcemanager.ResourceManager: Using Scheduler class: org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler方法二:通过YARN REST API查询
curl -X GET "http://<rm-address>:8088/ws/v1/cluster/scheduler"响应中包含scheduler-type字段表明当前调度器类型
方法三:检查配置文件
hadoop org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerType4.2 修改调度器类型的完整流程
更改调度器需要谨慎操作,以下是标准操作步骤:
停止YARN服务
stop-yarn.sh编辑yarn-site.xml
<!-- 设置Fair Scheduler --> <property> <name>yarn.resourcemanager.scheduler.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value> </property> <!-- 或者设置Capacity Scheduler --> <property> <name>yarn.resourcemanager.scheduler.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value> </property>准备调度器专属配置
- Fair Scheduler: 创建fair-scheduler.xml
- Capacity Scheduler: 编辑capacity-scheduler.xml
同步配置文件到所有节点
rsync -avz /etc/hadoop/conf/ node2:/etc/hadoop/conf/启动YARN服务
start-yarn.sh验证变更
yarn rmadmin -refreshQueues yarn node -list
重要:修改调度器会导致正在运行的作业重新排队,建议在维护窗口进行操作。不同调度器之间的队列配置不兼容,需要重新规划队列结构
5. 高级配置与性能调优
5.1 Capacity Scheduler精细调优
队列层次结构设计示例:
root ├── prod (40%) │ ├── etl (50%) │ └── reporting (50%) ├── dev (30%) │ ├── spark (60%) │ └── mapreduce (40%) └── adhoc (30%)关键配置参数:
<!-- 设置队列容量和最大容量 --> <property> <name>yarn.scheduler.capacity.root.prod.capacity</name> <value>40</value> </property> <property> <name>yarn.scheduler.capacity.root.prod.maximum-capacity</name> <value>60</value> </property> <!-- 设置用户限制 --> <property> <name>yarn.scheduler.capacity.root.prod.maximum-applications</name> <value>5000</value> </property> <property> <name>yarn.scheduler.capacity.root.prod.maximum-am-resource-percent</name> <value>0.2</value> </property> <!-- 启用资源抢占 --> <property> <name>yarn.scheduler.capacity.monitor.enable</name> <value>true</value> </property>5.2 Fair Scheduler高级特性
权重分配示例配置:
<allocations> <queue name="prod"> <minResources>10000 mb,10vcores</minResources> <maxResources>50000 mb,50vcores</maxResources> <weight>2.0</weight> <schedulingPolicy>fair</schedulingPolicy> </queue> <queue name="dev"> <minResources>5000 mb,5vcores</minResources> <maxResources>30000 mb,30vcores</maxResources> <weight>1.0</weight> <schedulingPolicy>fifo</schedulingPolicy> </queue> <user name="sparkuser"> <maxRunningApps>10</maxRunningApps> </user> </allocations>延迟调度优化:
<property> <name>yarn.scheduler.fair.locality.threshold.node</name> <value>0.8</value> </property> <property> <name>yarn.scheduler.fair.locality.threshold.rack</name> <value>0.7</value> </property>6. 常见问题排查与解决方案
6.1 调度器相关错误处理
问题一:作业长时间处于ACCEPTED状态
- 可能原因:
- 队列资源不足
- 调度器配置错误
- 资源请求过大
- 解决方案:
# 检查队列资源使用情况 yarn queue -status <queue-name> # 调整作业资源请求 set mapreduce.map.memory.mb=2048 set mapreduce.reduce.memory.mb=4096
问题二:Fair Scheduler不按预期分配资源
- 检查点:
- fair-scheduler.xml配置是否正确加载
- 权重设置是否合理
- 最小资源是否设置过大
- 是否有资源限制策略生效
- 调试命令:
yarn scheduler -conf <fair-scheduler.xml> yarn rmadmin -refreshQueues
6.2 性能优化检查清单
监控关键指标
- 调度延迟:yarn.resourcemanager.scheduler.monitor.enable=true
- 队列使用率:通过ResourceManager UI观察
- 资源碎片:检查节点报告中的剩余资源
配置建议
- 适当设置yarn.scheduler.minimum-allocation-mb/vcores
- 根据负载调整yarn.scheduler.maximum-allocation-mb/vcores
- 对于短作业,减小yarn.scheduler.increment-allocation-mb
日志分析要点
# 查找调度决策记录 grep "Scheduler allocation" yarn-resourcemanager.log # 检查资源请求匹配情况 grep "Unable to allocate container" yarn-resourcemanager.log
在实际生产环境中,我曾遇到一个典型案例:某电商平台在大促期间发现关键作业延迟严重,检查发现是Fair Scheduler的默认配置导致资源过于分散。通过为关键业务队列设置最小资源保证和更高权重,同时启用资源抢占功能,最终使核心作业的完成时间缩短了65%。这个案例告诉我们,调度器的默认配置往往需要根据业务特点进行深度定制。