恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

Yarn分布式资源调度原理深度解析:从架构到生产实践

  • 首页
  • 资讯中心
  • /
  • Yarn分布式资源调度原理深度解析:从架构到生产实践

相关资讯

多通信半径与加权跳距:DV-HOP定位精度改进算法详解 2026/10/20 14:46:45
微信小程序中文MD5加密完整方案:从编码原理到代码实现 2026/10/20 14:46:45
广义正态分布优化算法GNDO详解:原理、Python实现与调参实战 2026/10/20 14:46:45

最新资讯

EDC系统完整源码解析:从数据模型到审计追踪的临床数据管理
behave框架实战:用Python BDD让测试聚焦业务行为
Python AI编程入门指南:机器学习、深度学习、NLP与强化学习四大方向全解析
软考高项备考三个月一次通过:综合知识、案例分析与论文实战全攻略
工程师深度学习入门:从跑通Demo到项目落地
文本分类演进:从词袋到即插即用嵌入方案

今日推荐

高频变压器实战经验总结:磁芯选型、绕组工艺与故障排查全解析
U-Boot移植的关键:深入理解Kconfig配置系统与依赖关系
步进电机原理与调试全解析:从步距角到丢步排查

本周热门

基于GMM的语音识别系统原理与MATLAB实现详解
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

Yarn分布式资源调度原理深度解析:从架构到生产实践

发布时间:2026/10/20 14:46:45
Yarn分布式资源调度原理深度解析:从架构到生产实践 Yarn这个东西我刚接触大数据那会儿一直把它当成Hadoop自带的调度器来理解直到自己动手维护一套几十个节点的集群才发现它压根不是那么简单——它的定位是整个分布式生态的资源调度平台不止服务MapReduceSpark、Flink、Tez这些计算框架都能跑在它上面。标题里说的分布式资源调度原理如果你只停留在会配几个参数的层面一旦遇到队列阻塞、任务被杀、内存超限这种问题根本无从下手。这篇文章我会把Yarn从为什么需要它到一次调度到底走了哪些流程完整拆一遍再讲清楚三种调度器的工作原理、生产环境的容错机制以及我实际调参踩过的一些坑适合正在学分布式计算、或者已经开始维护集群但还没系统梳理过Yarn的人。1. 调度困局从哪来Yarn出现之前的大数据世界要理解Yarn得先回到它诞生之前的那个混乱年代。早期的大数据生态远没有现在这么成熟计算框架各自为战资源管理几乎全靠各框架自己完成。整个分布式系统看起来能跑但一旦规模上去问题就很扎眼。1.1 旧版MapReduce的瓶颈很多教程都会提到Hadoop 1.0时代的JobTracker TaskTracker架构但大部分只说它容易挂却没说清楚到底为什么挂。JobTracker身兼两职既要负责作业的调度又要负责任务的分配和监控。所有TaskTracker节点定期向它汇报心跳所有作业的进度信息都要汇总到它这里。集群一超过几百个节点JobTracker的内存和吞吐就成了硬瓶颈。更要命的是JobTracker是单点一旦宕机集群里所有正在运行的任务全部丢失没有自动恢复机制。这意味着你在跑一个十几个小时的大作业跑到第九个小时JobTracker挂了全部白跑。这种情况在真实生产环境里是灾难当时不少团队为了降低风险只能在凌晨业务低峰期提交大作业半夜还得有人盯着告警。1.2 为什么不能粗暴地多部署几个JobTracker普通人的第一反应可能是那就多做几个JobTracker做热备呗。但问题没这么简单一张资源表如果由多个master共同管理就涉及资源分配的一致性、分布式锁、状态同步实现难度不亚于重写一个调度系统。更关键的是MapReduce只是众多计算模型中的一种如果每个计算框架都各自搞一套资源管理Spark要一套、Flink又要一套底层资源怎么切分谁先谁后一个节点上同时跑两个框架的任务怎么保证互不干扰所以后来社区提出的思路不是继续打补丁而是把资源管理和计算框架彻底解耦下面统一由一个资源调度平台管节点、管内存、管CPU上面各个计算框架只提交自己的应用自己负责应用内部的执行计划。这个平台就是Yarn它的正式名称有很长一串但核心就是一句话分布式操作系统层面的资源调度中间层。说人话就是Yarn像是一个服务器机房管理员所有租户不同计算框架需要多少机器资源、什么时候用、用多久都由管理员统一安排而计算框架本身像是租户带来的生产设备怎么组织工人、怎么安排流水线那是租户自己的事。管理员不关心你生产的是什么他只负责保证资源公平、不超卖、有保障。2. Yarn系统架构解剖三大组件如何分工协作Yarn的整体架构可以浓缩成一个三角关系全局的ResourceManager、每个节点上的NodeManager、以及每个应用专属的ApplicationMaster。理解清楚这三者各自管什么Yarn的原理就懂了一半。2.1 ResourceManager全局资源大脑ResourceManager下面简称RM是整个集群的最高决策者它维护一张全局资源表知道每个NodeManager上报了多少可用资源也知道每个应用申请了多少、用掉了多少。它内部有两个核心子模块调度器Scheduler和应用管理器ApplicationsManager。调度器只负责一件事在满足约束条件的前提下决定把哪些资源分配给哪些应用。它不关心任务怎么执行、也不关心任务进度纯粹按策略做资源分配。ApplicationsManager则负责接收新提交的作业、与作业的ApplicationMaster协商启动事宜、在作业结束时回收资源并处理作业级别的异常。RM挂了会怎样在没有启用高可用的情况下RM宕机意味着所有在跑的应用都会因为丢失心跳而中断。所以生产集群里RM一定要做HA同时靠ZooKeeper做领导者选举和状态存储。这一点后面单独展开讲。2.2 NodeManager节点级资源管家NodeManagerNM是每台物理节点上的眼睛和手。它向RM定期发送心跳汇报自己当前的资源使用情况包括可用内存、CPU核数、磁盘状态等。RM做的资源分配决策最终都要落到NM头上RM说把2个Container给应用ANM就负责在本机创建这些Container的进程并监控它们的资源使用情况超了要杀掉正常结束了要回收资源并再次上报。有一个常被忽略的点NM只负责管理它自己所在节点的Container生命周期但它不负责调度。节点上哪个Container先跑、哪个后跑那是RM的调度器决定后下发到NM的。说白了NM就是一个没有决策权的执行者所有决策集中在RM。2.3 ApplicationMaster应用级协调者这是Yarn架构里最妙的一个设计也是很多人理解Yarn时的盲区。每个应用比如一个MapReduce作业、一个Spark作业在被接受之后RM会为它启动一个独立的ApplicationMasterAM这个AM本身也跑在一个Container里。AM是该应用内部的小大脑它向RM申请更多Container来运行task跟踪task的状态和进度遇到失败的任务还要自己决定重试。一个应用一个AM这套机制的好处是计算框架可以通过AM实现完全个性化的执行策略。MapReduce的AM和Spark的AM逻辑完全不同但它们在Yarn眼里都是一个正在申请资源的ClientYarn不需要理解每个应用的执行细节。这种平台层与应用层分离的设计相当于把并发控制这种分布式系统最复杂的问题从框架层剥离出来交给一个通用平台统一处理。2.4 组件间的通信与心跳机制Yarn的通信协议基于Protocol Buffers底层走RPC。心跳是这套系统保持活性认知的核心手段几个关键参数建议记牢NM向RM的心跳间隔默认1秒也就是yarn.resourcemanager.nodemanagers.heartbeat相关配置新版配置项是yarn.resourcemanager.nm-heartbeat-interval-msRM可以根据长时间收不到心跳的节点判定为超时失效。AM向RM的资源请求是异步的AM会不断发送allocate请求RM在心跳响应里带回来资源分配结果。NM会监控Container进程的资源使用量内存、CPU一旦发现超过申请范围先警告yarn.nodemanager.vmem-check-enabled开启时还要校验虚拟内存然后直接kill。心跳机制的微妙之处在于它既是状态同步手段也是活体探测手段但RPC通信本身有延迟集群规模增大后心跳风暴也是一个隐患。生产环境里我曾经把节点心跳频率从1秒调成3秒RM负载明显下降代价是任务启动和故障感知会慢一两秒。这个平衡要根据业务灵活调不是越频繁越好。3. 一次资源调度的完整生命周期从提交作业到Container回收原理讲得再多不如完整走一遍流程来得直观。下面以提交一个MapReduce作业为例拆解一次典型的Yarn调度全过程。这套流程对所有计算框架都通用只是具体协议略有差异。3.1 阶段一作业提交与AM启动你在命令行敲下hadoop jar xxx.jar之后客户端会创建一个作业对象内容包含jar包、输入路径、输出路径、各类配置。这个对象会被提交到RM的ApplicationsManager。RM收到提交请求后做两件事一是校验ACL权限和队列配额二是让调度器为这个作业分配一个启动AM用的Container。有意思的是AM占用的这个Container是要排队等调度的不是提交后立刻就有。如果当前集群资源很忙你的作业可能长时间停留在ACCEPTED状态看着就像卡住了实际是在等调度器给它派发第一个Container。很多新手第一次见到作业一直不跑第一反应是集群挂了其实查一查RM页面的Application状态就知道它在等资源。调度器分配出这个Container后RM会告诉对应的NM在指定Contianer里启动ApplicationMasterNM随后把AM进程拉起来。AM启动后第一件事就是向RM注册自己建立一条专属于这个应用的RPC连接。到这一步作业提交阶段正式结束。3.2 阶段二资源申请与Container分配AM启动后就会根据应用自身的执行计划向RM发起资源申请。以MapReduce为例AM会优先申请运行Map task的ContainerMap全部跑完后再申请Reduce task的Container。申请消息里会带上资源规格比如内存要4GB、CPU要2核还可能有数据本地性偏好——比如某个任务如果能把Container调度到它要读取的数据所在节点上就能避免跨网络拷贝。这里要理解Yarn调度器的核心逻辑调度器只根据当前集群资源状态做短期决策它不会提前为某个应用预留资源也不会知道这个应用未来总共需要多少资源。它每次只回答一个问题现在这批资源给谁最合适所以要求高效利用本质上是调度策略和队列配额的博弈——不同应用抢同一块资源时分配结果完全由调度器决定。Container分配成功后会下发到目标NMNM负责实体化这个Container。注意一个Container从被分配到真正可用中间还有一段启动时间JVM启动、环境初始化这就是为什么你有时候看任务的开始时间比作业的提交时间晚了很久。3.3 阶段三任务运行、进度汇报与资源回收Container里跑起来的task会通过AM向客户端汇报进度。MapReduce作业的整体进度、阶段百分比、当前运行到哪个task都是AM汇总后从RM的页面暴露出去的。当应用的所有任务都跑完AM会向RM发送应用完成的消息RM负责清理该应用的AM Container并把资源标记为空闲。NM盯着这些Container的进程发现进程退出就会把资源状态从占用中改回可用同步给RM。到这里一次调度生命周期才算真正闭环。一个容易被忽视的点Container的资源是会被NM强制回收的。如果一个Container申请了8GB内存但里面运行的任务因为数据倾斜等原因实际吃掉9GBNM会毫不犹豫地杀掉它。所以生产环境的作业内存参数比如MapReduce的mapreduce.map.memory.mb必须留足余量卡着上限设参数早晚要被NM制裁。4. 三种调度器深度拆解FIFO、Capacity和Fair怎么选如果说前面的角色分工是Yarn的骨架调度器就是Yarn的脾气。同一个集群换一种调度器用户体验可能天差地别。Yarn内置了三种调度器FIFO Scheduler、Capacity Scheduler、Fair Scheduler。默认是Capacity但默认不代表它适合你得搞懂它们各自的取舍。4.1 FIFO Scheduler简单但致命FIFO是队列式的先来先服务调度器按照作业提交顺序依次分配资源前一个作业的资源需求没满足之前后一个作业只能干等。它的优势是零配置、逻辑极致简单坏处是完全没有隔离能力一个大作业独占集群其他所有作业全部排队。我在一些测试环境见过有人图省事用FIFO结果就是某天晚上一个跑全量数据的大作业提交上去第二天早上所有开发同学的任务全部卡死。这不是Yarn的问题是选型问题。FIFO只适合单用户、作业量小、且作业时间都比较短的极简场景。4.2 Capacity Scheduler面向多租户的排队模型Capacity Scheduler是目前生产环境的主流选择核心思想是多队列 资源比例 弹性借用。管理员配置若干队列比如root.dev、root.prod每个队列占用集群总资源的一个百分比。调度时作业先被分到某个队列队列内部再按FIFO或优先级排队。它的一个关键特性是弹性如果root.prod队列的资源没用满root.dev队列可以临时借用root.prod的空闲资源。但一旦root.prod有新的作业进来借出去的资源会被逐步回收。回收是靠kill正在借用的Container完成的这个过程叫抢占对运行中的任务有杀伤力。配Capacity Scheduler时要特别注意两点一是每个队列的maximum-capacity要合理设置否则容易出现A队列把整个集群都占了B队列的作业永远起不来二是AM资源比例yarn.scheduler.capacity.maximum-am-resource-percent这个默认是0.5意思是该队列最多把一半的资源用于启动AM如果AM过多作业会卡在申请第一个Container那一步。4.3 Fair Scheduler按应用数量的动态平衡Fair Scheduler的目标和Capacity不太一样它追求的是在同一队列内让所有运行中的应用获得大致均等的资源份额。如果集群里有10个应用在跑Fair会试图让每个应用各拿约10%的资源如果突然新来了10个应用份额会重新均分变成每个约5%。这里涉及一个非常实用的策略叫延迟调度。新到的任务如果因为数据本地性问题数据在自己所在的节点但那个节点暂时没资源Fair不会立即放弃而是等一小段时间再尝试等1-2轮心跳周期。这个设计对分布式计算性能影响巨大因为跨节点拉数据的开销远比多等一两秒大得多。对应参数是fair-scheduler.xml里的locality-delay-node-ms和locality-delay-rack-ms。Fair还支持基于权重weight的配额分配允许某些重要应用在资源竞争中优先获得更多份额。灵活是它的优点但相比之下它也更容易出现资源碎片和配额漂移在生产环境对运维监控的要求更高。4.4 调度器选型的决策参考三者选谁不能只看哪个好要看你的资源诉求是什么。我做了一张对比表供参考对比维度FIFO SchedulerCapacity SchedulerFair Scheduler核心思想先来先服务多队列按比例隔离多应用动态均分多租户隔离无强队列间硬隔离弹性借用中应用间软公平作业等待时间大作业后面全堵看队列配额相对均摊配置复杂度极低中中高典型场景个人测试集群多部门共享生产集群多应用混跑、追求利用率的场景抢占能力无支持支持我个人的倾向很明确生产环境如果部门边界清晰、各团队有不同的SLA要求用Capacity如果是数据平台统一运维、应用五花八门、希望大任务小任务都能跑Fair更合适FIFO只存在于教学和单机测试里别把它拿到生产环境冒险。5. 生产环境不可忽略的可靠性机制容错、抢占与隔离调度原理讲完了但这些机制如果不在真实集群里经历过一轮基本就是纸上谈兵。这一节我把生产环境一定会遇到的几个可靠性问题逐一展开。5.1 RM的高可用与状态恢复RM是集群的决策中心它挂了所有调度都会停摆。Yarn提供了两种高可用方案一是yarn.resourcemanager.ha.enabled开启部署主备RM通过ZooKeeper做选举和状态存储二是用Embedded ZooKeeper功能类似但少了外部依赖成本。主备切换的细节这里不展开但有一个关键点要记住AM的状态是不能从RM故障中自动恢复的除非框架自身支持AM重启。因为AM是每个应用私有的RM恢复后虽然知道这个应用存在但AM已经因为失去心跳被NM清理掉了。MapReduce和Spark对AM都有一定的重试恢复支持但恢复过程会丢掉已运行任务的进度实际效果视具体版本而定。我见过一个部署事故某团队把RM的HA配好了但忘了配置ZK的地址参数结果两个RM同时认为自己才是主节点脑裂集群调度完全错乱。所以配置HA不是把开关打开就完事必须先在测试集群里演练主备切换全流程确认行政切换和故障自动切换两个场景都正常再上生产。5.2 抢占机制与驱逐成本抢占是调度器保证SLA说一不二的底气当低优先级的应用占用了资源而高优先级的应用需要这些资源时调度器会强制终止低优先级应用的Container来腾出空间。被抢占的Container内部的task会直接失败由AM负责重试。听起来简单但实际生产中我强烈建议谨慎开启抢占或者把抢占的触发条件调得很保守。原因很简单被抢占的Container白白浪费了已经执行部分的工作如果抢完立刻又空出来反而比等一等更亏。Fair Scheduler通过yarn.scheduler.fair.preemption开关控制有些版本默认关闭这是好事——开了之后突发的大任务可能频繁抢占小任务导致小任务长时间无法完成。更务实的做法是用队列配额和权重把资源冲突在源头压制住让抢占只作为最后一道底线而不是日常机制。5.3 资源隔离的真正含义Yarn的资源隔离分为两个层面第一层是调度层隔离也就是RM只按你申请的规格分发资源超了NM会管第二层是执行层隔离Yarn默认用cgroups能对CPU做更细粒度的控制用yarn.nodemanager.container-executor.class配成LinuxContainerExecutor后才能真正生效。很多团队在这里有误区以为设置了container的内存大小进程就一定会被限制在那个范围。实际上如果你用的是默认的DefaultContainerExecutorNM对CPU的限制非常宽松对内存也只是靠监控进程的物理内存和虚拟内存来判断超过再杀。真正的防超卖还得靠cgroup 禁用的swap空间配合否则一个JVM因为自身的堆外内存不受控就可能在Yarn眼里变成超额容器被误杀。5.4 节点标签异构集群的高级调度如果你集群里既有普通CPU节点又有带GPU的节点跑深度学习或高性能计算Yarn的基础调度器是感知不到这种异构的它只会当成这节点有好多资源。这时候就需要节点标签把某些队列或某些作业绑定到特定节点上。配置思路是先给节点打标签比如yarn.node-labels.manager配好之后在RM页面或命令行给节点标记dx再在调度器配置里指定队列允许使用的标签。这样一来GPU作业只调度到打GPU标签的节点普通作业也不至于误占GPU节点。节点标签还能用在安全合规场景——比如某些数据只允许在特定机器上处理就可以用标签把作业锁定在那一批机器上。这个功能强烈建议在运维手册里固化下来因为集群大了之后节点异构几乎是必然事件。6. 从原理到落地集群参数调优与我看过的坑最后这部分送点硬货把我维护Yarn集群时总结下来的调参经验和一个印象最深的排障过程分享出来。这里面的参数不是拍脑袋给的每一条背后都有对应的问题场景。6.1 基础资源参数宁可留余量不要卡上限单节点可用内存的设定是很多问题的源头。yarn.nodemanager.resource.memory-mb习惯上按物理内存的一定比例设置但要注意给操作系统、HDFS的DataNode、系统进程留够空间。一个常见的低配错误32GB内存的机器管理员直接把30GB全划给Yarn结果节点稳定性极差RM频繁收到NM心跳断连实际原因是机器内存耗尽触发了OOM连NM自己都难以存活。对典型配置我有一个粗算公式给Yarn的内存 物理内存 - 8GB系统HDFS其他常驻进程 - 内存页缓存预留。但每台机器角色不同比如同时跑HDFS和Yarn的机器那至少要额外留10GB给DataNode的页缓存。Container的规格分配也要和yarn.scheduler.minimum-allocation-mb、yarn.scheduler.maximum-allocation-mb配合设置Core数同理。minimum决定最小的资源粒度太小了会让分配请求数急剧膨胀太大又浪费典型的8GB/节点集群设4GB起步比较常见。具体按作业负载定没有万能值但原则是提交作业时框架侧的map.memory.mb和reduce.memory.mb必须比Yarn的Container规格略小或相等否则NM会因为申请超限直接把Container判死。6.2 调度器队列配置示例一个可参考的Capacity配置下面给一个精简版的capacity-scheduler.xml配置适合两个团队共享一个集群的场景配置文件里必须有具体的队列结构和配额configuration property nameyarn.scheduler.capacity.root.queues/name valuedev,prod/value /property property nameyarn.scheduler.capacity.root.dev.capacity/name value30/value /property property nameyarn.scheduler.capacity.root.prod.capacity/name value70/value /property property nameyarn.scheduler.capacity.root.prod.maximum-capacity/name value85/value /property property nameyarn.scheduler.capacity.root.dev.maximum-capacity/name value40/value /property property nameyarn.scheduler.capacity.root.prod.maximum-am-resource-percent/name value0.3/value /property /configuration记住几个细节dev.capacity30意味着该队列默认享有集群30%的容量如果同时配置了maximum-capacity40意味着它最多能借用到集群总资源的40%再多了会被触发回收这能有效防止开发任务在低峰期把整个集群占满导致生产作业晚上提交的时候无资源可用。从命令行提交作业时记得用-Dmapreduce.job.queuenameprod参数指定队列否则会全部进默认队列调度策略直接白配。我见过不止一次管理员配了三个月队列一查所有作业全在root.default里排队气得当场想砸键盘。6.3 一次让我印象深刻的排查经历有一段时间集群经常出现作业卡在ACCEPTED状态的告警整个集群利用率看起来也不高但新作业就是分配不到资源。起初我怀疑是某个大作业占光了配额一查root.prod队列的使用率确实接近100%但通过Yarn的ResourceManager页面看节点Container分布发现许多NodeManager上报的内存使用和实际分配出去的Container合计对不上。后来用命令行逐个节点查容器进程发现有一批Spark任务申请的是16GB的Container但JVM启动参数里堆外内存和线程栈配得很高导致实际进程占了20多GBNM的内存在进程层面早就超限只是因为虚拟内存校验在某些容器执行环境下失效NM没及时kill系统却在物理内存紧张时开始频繁swap。后来我们把容器执行器换成了LinuxContainerExecutor开启cgroups重启NM并把Spark作业的executor.memoryOverhead调大问题才算彻底解决。这个坑的意义在于Yarn的资源模型是逻辑资源模型它对内存的认知完全来自进程上报和参数配置做不到对JVM堆外、线程栈、mmap的精细化控制。你在调资源参数时不要只盯着Container的规格还要问一句跑在上面的计算框架实际会额外吃多少资源6.4 运维层面的几个实用建议最后几条经验按优先级排列日志先集中再排查开启yarn.log-aggregation-enable把Container日志聚合到HDFS排障时不必逐个节点翻日志。排查ACCEPTED状态的作业先看AM日志比看RM日志快得多。监控必须盯队列级指标只看集群总资源利用率远远不够队列的pending、running、allocated这三个指标分开盯才能真正发现谁在饿死谁。不要忽视客户端侧配置很多问题其实出在提交作业那一侧比如yarn.client.fail-max-attempts和yarn.resourcemanager.connect.retry-interval配置不合理客户端会反复重试失败看起来像是集群不接受作业。版本差异是最大的坑Yarn在不同版本的参数名和默认值差别很大网上搜到的老教程经常在最新版本上失效任何调优都以你当前部署版本的官方文档为准。我自己在维护Yarn的过程里最大的体会是它本质上是一套很公平的资源买卖系统公平的前提是你会精确描述自己需要什么、愿意等待多久。参数不是越多越好很多时候第一次调参就把一个核心参数设置好比堆一堆花哨的高级特性值钱得多。如果你正在管理一套生产集群建议把上面第三部分的作业生命周期画成一张图贴到墙上每次排障都先回到那张图你会发现90%的调度问题都是某个环节的心跳、申请或回收没按预期发生。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号