Yarn深度解析:分布式资源调度的核心框架
YARN(Yet Another Resource Negotiator)是 Hadoop 生态系统中的资源管理和调度平台,负责协调集群中的计算资源(CPU、内存等)并为应用程序分配资源。它将 MapReduce v1 中的 JobTracker 功能拆分为 资源管理 和 作业监控 两部分,实现了资源与应用程序的解耦,支持多种计算框架(如 MapReduce、Spark、Flink 等)共享集群资源。本文将从 YARN 的架构、核心组件、调度策略到实战配置,全面解析其工作原理与优化方法。
YARN 核心架构与组件
YARN 采用 主从架构,由一个全局的 ResourceManager
、每个节点上的 NodeManager
、每个应用程序的 ApplicationMaster
以及资源容器 Container
组成。整体架构如下:
flowchart TD subgraph 集群节点 A[ResourceManager
全局资源管理器] B[NodeManager
节点资源管理器] C[NodeManager
节点资源管理器] end subgraph 应用程序 D[ApplicationMaster
应用主控] E[Container
资源容器] F[Container
资源容器] end A -- 资源分配 --> B A -- 资源分配 --> C A -- 启动/监控 --> D D -- 申请资源 --> A D -- 管理任务 --> E D -- 管理任务 --> F B -- 提供容器 --> E C -- 提供容器 --> F
ResourceManager(RM):全局资源总管
ResourceManager
是 YARN 的核心组件,负责集群资源的全局管理和调度,主要功能包括:
核心职责
- 接收客户端请求:处理应用程序的提交、终止等请求;
- 资源分配与调度:将集群资源(CPU、内存)以
Container
形式分配给应用程序; - 监控 NodeManager:跟踪节点状态,处理节点故障;
- 启动与监控 ApplicationMaster:为每个应用程序启动
ApplicationMaster
,并监控其生命周期。
核心模块
- 调度器(Scheduler):根据策略分配资源(不负责监控应用);
- 应用管理器(ApplicationsManager):管理应用程序的生命周期(启动 AM、处理失败重试)。
NodeManager(NM):节点资源管家
NodeManager
是每个节点上的资源管理器,负责本节点的资源管理和任务监控:
核心职责
- 资源管理:管理节点上的 CPU、内存等资源,向
ResourceManager
汇报节点资源使用情况; - 容器管理:创建、启动、停止
Container
,监控容器的资源使用(如内存超限则杀死容器); - 与 AM 交互:接收
ApplicationMaster
的指令,执行具体任务(如启动 Map/Reduce 任务); - 日志管理:收集容器的日志并存储到 HDFS 或本地磁盘。
ApplicationMaster(AM):应用程序主控
ApplicationMaster
是每个应用程序的 “管家”,负责协调应用程序的资源申请和任务执行:
核心职责
- 资源申请:向
ResourceManager
申请运行任务所需的Container
; - 任务调度:将申请到的
Container
分配给具体任务(如 MapTask、ReduceTask); - 任务监控:跟踪任务状态,处理任务失败(如重试失败任务);
- 进度汇报:向
ResourceManager
汇报应用程序进度和资源使用情况。
典型流程
- 客户端提交应用程序,
ResourceManager
为其启动ApplicationMaster
; ApplicationMaster
分析应用需求(如 MapReduce 的切片数),向ResourceManager
申请Container
;ApplicationMaster
与NodeManager
交互,在Container
中启动任务;- 任务完成后,
ApplicationMaster
向ResourceManager
汇报并注销。
Container:资源容器
Container
是 YARN 中的资源抽象,封装了节点上的 多维度资源(内存、CPU 核心数等),是应用程序运行任务的基本单位:
核心特性
- 资源隔离:通过 Linux Cgroups 或 Docker 实现资源隔离,防止任务间资源抢占;
- 生命周期:由
NodeManager
创建和销毁,与任务生命周期绑定; - 资源描述:每个
Container
的资源需求以<内存, CPU>
形式定义(如2GB 内存 + 2 核 CPU
)。
YARN 资源调度策略详解
YARN 的调度器(Scheduler)是 ResourceManager
的核心模块,负责根据策略将集群资源分配给应用程序。YARN 提供三种主流调度器,需根据集群场景选择。
FIFO 调度器(先进先出调度器)
原理:所有应用程序按提交顺序排成一个队列,先提交的应用优先分配资源,独占集群直到完成。
特点
- 优点:实现简单,无配置成本;
- 缺点:不支持多队列和资源共享,大应用会阻塞小应用(如一个大 MapReduce 作业会占用所有资源,后续小作业需等待);
- 适用场景:单用户、批处理场景,无资源共享需求的集群。
Capacity 调度器(容量调度器)
原理:将集群资源划分为多个队列,每个队列配置固定容量(如 80%/20%),队列内应用按 FIFO 顺序调度,空闲队列的资源可被其他队列临时借用。
核心特性
- 多队列隔离:支持不同队列(如生产队列、开发队列),避免资源争抢;
- 容量保障:每个队列有固定资源比例(如
daily
队列占 80%,dev
队列占 20%); - 资源弹性:空闲队列的资源可被其他队列临时使用,但不能超过队列最大容量(如
daily
队列最大使用 90%,预留 10% 给dev
队列); - 用户限制:限制单个用户在队列中占用的资源比例,防止垄断。
配置示例(capacity-scheduler.xml
)
1 | <!-- 定义 root 下的子队列 --> |
Fair 调度器(公平调度器)
原理:所有应用程序动态共享资源,每个应用最终获得公平的资源份额(如两个应用共享一个队列,则各获 50% 资源),资源分配基于 “缺额”(理想资源与实际资源的差距)。
核心特性
- 公平共享:同一队列内应用按 “缺额” 分配资源,缺额越大优先级越高;
- 多队列与权重:支持队列权重配置(如
daily
权重 80,dev
权重 20,资源按权重比例分配); - 优先级支持:应用可设置优先级,高优先级应用获得更多资源;
- 弹性资源:空闲资源自动分配给最需要的应用,无需等待。
配置示例(fair-scheduler.xml
)
1 | <allocations> |
调度器选型建议
调度器类型 | 适用场景 | 核心优势 | 缺点 |
---|---|---|---|
FIFO | 单用户、批处理 | 简单、无配置 | 资源利用率低,大作业阻塞小作业 |
Capacity | 多租户、生产环境 | 资源隔离、容量保障 | 配置复杂,空闲资源利用率较低 |
Fair | 多租户、共享集群 | 资源利用率高、动态平衡 | 小作业启动延迟,配置较复杂 |
YARN 核心配置与参数调优
YARN 的性能与资源配置密切相关,需根据集群规模(节点数、CPU、内存)合理设置参数,避免资源浪费或不足。
核心配置文件
yarn-site.xml
:YARN 核心配置(如 ResourceManager 地址、调度器类型);capacity-scheduler.xml
:Capacity 调度器配置;fair-scheduler.xml
:Fair 调度器配置。
关键参数配置(yarn-site.xml
)
资源管理参数
参数 | 说明 | 推荐配置(8 核 16GB 节点) |
---|---|---|
yarn.nodemanager.resource.memory-mb |
节点可分配总内存(MB) | 12288(12GB,预留 4GB 给系统) |
yarn.nodemanager.resource.cpu-vcores |
节点可分配总 CPU 核心数 | 6(预留 2 核给系统) |
yarn.scheduler.minimum-allocation-mb |
单个 Container 最小内存(MB) | 1024(1GB) |
yarn.scheduler.maximum-allocation-mb |
单个 Container 最大内存(MB) | 8192(8GB) |
yarn.scheduler.minimum-allocation-vcores |
单个 Container 最小 CPU 核心数 | 1 |
yarn.scheduler.maximum-allocation-vcores |
单个 Container 最大 CPU 核心数 | 4 |
调度器配置
1 | <!-- 指定调度器类型(Capacity/Fair) --> |
容器监控与容错
参数 | 说明 | 推荐配置 |
---|---|---|
yarn.nodemanager.pmem-check-enabled |
是否检查物理内存超限 | false(避免任务因内存波动被杀死) |
yarn.nodemanager.vmem-check-enabled |
是否检查虚拟内存超限 | false |
yarn.resourcemanager.am.max-attempts |
ApplicationMaster 最大重试次数 | 2 |
yarn.application.fail-fast |
是否快速失败(不重试) | false(生产环境启用重试) |
调度器参数调优(Capacity 调度器示例)
1 | <!-- 集群最大并发应用数 --> |
YARN 应用提交与监控
应用提交流程
以 MapReduce 应用为例,YARN 应用提交步骤如下:
- 客户端向
ResourceManager
提交应用,请求启动ApplicationMaster
; ResourceManager
分配第一个Container
并在节点上启动ApplicationMaster
;ApplicationMaster
向ResourceManager
申请运行任务的Container
;ApplicationMaster
与NodeManager
交互,在Container
中启动 Map/Reduce 任务;- 任务运行完成后,
ApplicationMaster
向ResourceManager
汇报,应用结束。
监控工具
YARN Web UI:通过
http://<ResourceManager节点>:8088
查看集群状态、应用列表、资源使用情况;命令行工具:
1
2
3yarn application -list # 查看运行中的应用
yarn application -kill <application_id> # 终止应用
yarn node -list # 查看节点状态
YARN 常见问题与优化策略
1. 资源不足导致应用失败
- 症状:应用启动失败,日志显示
Container is running beyond memory limits
; - 原因:
Container
内存配置不足,或应用实际内存需求超过配置; - 解决:
- 调大
yarn.scheduler.maximum-allocation-mb
增加单个 Container 最大内存; - 优化应用内存需求(如 MapReduce 中调大
mapreduce.map.memory.mb
)。
- 调大
2. 节点故障导致任务失败
- 症状:
NodeManager
宕机,导致其上Container
被杀死; - 解决:
- 启用 YARN 容错机制(
yarn.resourcemanager.am.max-attempts
设置重试次数); - 配置节点健康检查(
yarn.nodemanager.health-checker.script.path
),自动隔离故障节点。
- 启用 YARN 容错机制(
3. 调度延迟导致小应用等待
- 症状:小应用提交后长期处于
ACCEPTED
状态,等待资源; - 解决:
- 使用 Fair 调度器,小应用可快速获得资源;
- 为小应用配置高优先级(Capacity/Fair 调度器支持优先级)。
4. 内存碎片问题
- 症状:集群总内存充足,但因
Container
最小内存配置过大,导致小应用无法分配资源; - 解决:调小
yarn.scheduler.minimum-allocation-mb
(如从 2GB 改为 1GB),提高内存利用率。