公司动态
深入解析YARN ResourceManager:架构、高可用与性能调优实战
1. 项目概述从“资源管家”到分布式系统基石在任何一个稍具规模的分布式计算集群里资源管理都是一个无法绕开的核心命题。想象一下你管理着一个拥有数百台服务器的机房每天有成百上千的计算任务比如大数据分析、机器学习训练提交上来每个任务对CPU、内存的需求各不相同有的像“巨无霸”需要独占多台机器有的像“小点心”只需零星资源。如何高效、公平、稳定地把有限的物理资源分配给这些任务确保集群整体吞吐量最大同时避免任务间“打架”或资源浪费这就是ResourceManager资源管理器要解决的终极问题。提到ResourceManager很多人会立刻联想到Apache Hadoop YARN。确实YARN的ResourceManager是这一概念的经典实现它让Hadoop从单一的MapReduce计算框架进化成了一个通用的资源管理与作业调度平台。但ResourceManager的设计思想早已超越了Hadoop生态成为了现代分布式系统如Kubernetes的kube-scheduler、Apache Mesos等中不可或缺的“大脑”组件。简单来说它就是集群的“资源大管家”和“任务调度中心”负责接收任务请求盘点家底集群资源并做出决策哪个任务可以在哪台机器的哪个容器里运行。最近在开发者社区关于资源管理的讨论依然火热。比如前端同学在纠结yarn和npm的命令区别与安装效率npm install yarn 两秒就没了这类问题背后其实也是包管理器的资源协调能力运维工程师在离线部署ubuntu20.04 nfs服务端组件嵌入式工程师在查阅stm32f103c8t6或uln2003a的引脚功能定义——这些看似分散的话题其内核都是对“资源”软件包、存储服务、硬件引脚的精确管理和功能抽象。而一个强大的ResourceManager正是将这种管理能力从单机扩展到集群规模的关键。本文将深入拆解一个典型ResourceManager以YARN为蓝本但其架构思想具有普适性的详细组件及其功能让你不仅知道它怎么工作更理解它为何这样设计以及在实际运维和开发中如何与之高效协作。2. ResourceManager核心架构与组件拆解一个成熟的ResourceManager绝非一个单一进程而是一个由多个协同工作的子组件构成的复杂系统。它的设计遵循着“职责分离”和“可扩展”的原则将资源管理、应用调度、状态持久化等关注点解耦。下面我们以YARN ResourceManager为基准模型将其大卸八块看看每个部件的具体职责。2.1 核心调度器决策大脑调度器是ResourceManager的心脏它决定了资源的分配策略。YARN支持多种调度器常见的有FIFO Scheduler先进先出调度器最简单所有应用按提交顺序排队依次执行。缺点显而易见一个大的长任务会阻塞后面所有小任务不适合共享集群。Capacity Scheduler容量调度器这是许多企业的首选。它将集群资源划分为多个队列例如dev、prod、research每个队列被分配一定的资源容量比如30%的集群资源。队列内部可以采用FIFO或DRF等策略。它的核心优势是资源隔离和弹性一个队列资源空闲时可以临时借给其他队列使用保证资源利用率当队列需要自己的资源时借出的资源又会被收回。这很好地平衡了公平性与利用率。Fair Scheduler公平调度器目标是让所有运行中的应用随着时间的推移能平均地获得等量的资源。它会动态调整资源分配新提交的应用可以快速获得资源启动而不会饿死。更适合多租户、交互式查询场景。调度器选型心得选择哪种调度器取决于你的集群 workload工作负载。如果是生产、开发环境混合的共享集群Capacity Scheduler是更稳妥的选择因为它通过队列实现了业务隔离和资源保障。如果是纯粹的实验性或研究性集群追求极致的资源利用率和快速响应Fair Scheduler可能更合适。在实际配置中Capacity Scheduler的yarn.scheduler.capacity.root.queues配置项是定义队列结构的起点务必仔细规划。2.2 应用管理器应用生命周期管家应用管理器负责管理整个集群上所有应用程序的生命周期包括应用的提交、启动、运行监控和完成清理。它内部维护着每个应用的ApplicationMasterAM的上下文信息。功能流程接收提交当客户端通过ResourceManager REST API或ClientRMService提交一个应用时应用管理器会为其创建一个ApplicationId并准备一个上下文环境。调度AM它与调度器协商为这个应用的ApplicationMaster申请第一个容器Container。这个容器是特殊的因为它将运行AM进程而AM负责向RM申请更多资源来运行真正的计算任务如MapReduce的Map Task。状态管理跟踪应用状态NEW、NEW_SAVING、SUBMITTED、ACCEPTED、RUNNING、FINISHED、FAILED、KILLED并将状态变化同步给客户端和持久化存储。协调终结当应用完成成功或失败或用户主动杀死应用时应用管理器负责通知相关组件清理资源并最终将应用从活动列表移至历史记录。2.3 节点管理器通信器集群触手节点管理器通信器是ResourceManager与每个从节点上的NodeManagerNM进行RPC通信的模块。NM定期默认1秒向RM发送心跳汇报本节点的健康状况、可用资源CPU、内存等以及其上运行的容器状态。核心职责心跳处理接收并处理来自所有NM的心跳。这是RM感知集群实时状态的唯一途径。资源汇报从心跳中聚合整个集群的可用资源总量为调度器提供决策依据。指令下达通过心跳响应向NM下达指令包括启动新容器、清理已完成的容器等。节点状态管理标记不健康或失联的节点UNHEALTHY、DECOMMISSIONED、LOST并将其资源从调度池中移除避免将任务调度到问题节点上。实操避坑心跳间隔yarn.nm.liveness-monitor.expiry-interval-ms和RM对NM的判定死亡时间需要合理配置。在网络不稳定的大集群中过短的心跳超时可能导致节点被误判为死亡引发不必要的任务重新调度。通常可以适当调大超时时间例如从10分钟调到20分钟但要以牺牲故障检测速度为代价。2.4 客户端通信服务对外API网关这是ResourceManager面向用户和外部系统的窗口通常通过REST API和RPC接口如Hadoop RPC暴露。它处理所有来自客户端的请求。主要接口应用提交接收新的应用提交请求。应用状态查询客户端可以通过ApplicationId查询应用当前状态、进度、最终诊断信息等。应用控制支持杀死应用、获取应用日志等管理操作。集群指标查询提供集群总资源、已用资源、队列信息、节点列表等监控数据。这些数据是集群监控大盘如Grafana的重要来源。2.5 状态存储与恢复记忆中枢对于生产系统ResourceManager必须是有状态的且状态必须持久化以应对RM进程重启或故障切换。状态存储组件负责将关键元数据如已提交的应用、队列配置、节点标签等写入可靠的存储如ZooKeeper、LevelDB或HDFS。持久化内容应用元数据ApplicationMetaData包括ApplicationId、用户、队列、提交时间等。应用状态特别是那些已提交但尚未运行完成的应用状态。委托令牌用于安全认证。AM尝试次数用于限制失败重试。恢复流程当RM主节点故障备用RM被激活时它会从状态存储中加载这些持久化状态从而恢复集群到故障前的某个一致点然后重新与NM建立连接恢复运行中的应用。对于运行中的应用其AM会向新的RM重新注册继续工作。2.6 安全管理器守门人在多租户集群中安全管理至关重要。安全管理器集成认证如Kerberos、授权如Access Control Lists和权限管理。认证验证客户端、AM和NM的身份。通常通过Kerberos票据或委托令牌实现。授权检查用户是否有权限提交应用到某个队列、查看某个应用的状态或杀死他人的应用。YARN使用Service Authorization和每个队列的ACLyarn.scheduler.capacity.queue-path.acl_submit_applications进行控制。令牌管理管理容器令牌、AM令牌等确保容器只能在指定的NM上启动且AM只能为自己的应用申请资源。2.7 Web UI与监控接口可视化控制台ResourceManager内置了一个Web UI默认端口8088为管理员和用户提供了直观的集群视图。这是日常运维最常接触的界面。主要页面集群概览显示集群总资源、已用资源、活跃节点数、调度器类型等。节点列表展示所有NM节点包括状态、地址、可用资源、已用资源可以点击查看单个节点详情和其上运行的容器。应用列表显示所有应用运行中、已完成、已失败支持按用户、队列、状态筛选。可以查看应用详情、日志和杀死应用。调度器信息如果使用Capacity Scheduler可以查看各个队列的资源使用情况和配置。3. 核心工作流程深度解析理解了静态组件我们再通过一个经典的应用提交与执行流程动态地看这些组件如何联动。这个过程就像一场精密的交响乐演出。3.1 应用提交与初始化客户端调用用户运行yarn jar命令或通过编程APIYarnClient提交应用。客户端首先会从hadoop配置中定位到ResourceManager的地址。创建应用上下文客户端将应用所需的资源AM所需容器规格、JAR包、命令、配置等打包成一个ApplicationSubmissionContext对象。提交至RM客户端通过ClientRMService的RPC接口将上下文提交给ResourceManager。安全验证与接收安全管理器验证用户身份和权限。验证通过后应用管理器为新应用生成唯一的ApplicationId并将其状态置为SUBMITTED同时将应用元数据持久化到状态存储。随后应用状态转为ACCEPTED意味着RM已接受该应用等待调度。3.2 调度与ApplicationMaster启动AM资源申请应用管理器代表这个新应用向调度器发起一个资源请求为ApplicationMaster申请一个容器。请求中包含了AM所需的资源量如1个vCore2GB内存。调度器决策调度器根据队列容量、优先级、资源可用性等策略决定在哪个NM上分配这个容器。假设它选中了NodeManager-A。分配容器调度器生成一个Container对象指定其ID、所在主机、资源量、令牌等。启动指令下发应用管理器通过节点管理器通信器在下一个心跳响应中向NodeManager-A发送StartContainerRequest包含启动AM所需的全部信息本地化资源、环境变量、启动命令。NM启动AMNodeManager-A收到指令后准备环境下载JAR包到本地创建一个独立的进程或cgroups容器来运行用户指定的AM主类如MRAppMaster。3.3 任务资源协商与执行AM向RM注册AM启动后第一件事就是向ResourceManager的ApplicationMasterService属于应用管理器的一部分注册自己告知RM“我活过来了”并获取AM RPC端口和跟踪URL。AM申请任务资源AM根据应用逻辑例如需要处理100个输入分片就需要100个Map Task容器向RM的调度器发起资源请求。这些请求可以指定资源偏好如数据本地性同一个节点、同一个机架、任意节点。RM分配任务容器调度器持续处理来自所有活跃AM的资源请求。当有资源可用时它会为请求分配容器并通过心跳响应将Container分配信息返回给对应的AM。AM启动任务AM收到分配的容器列表后与对应的NM通信启动真正的计算任务容器如MapTask或ReduceTask。任务容器中运行的是用户代码。状态汇报循环任务容器定期向AM汇报进度和状态。AM则聚合应用的整体进度并定期向RM发送心跳汇报应用状态和新的资源需求。RM将应用状态更新到Web UI和客户端查询接口。3.4 应用完成与清理任务完成所有计算任务完成后AM向RM发送FinishApplicationMaster请求报告应用最终状态SUCCEEDED。RM确认RM的应用管理器收到消息后将应用状态置为FINISHED并通知所有相关的NM清理AM容器和任务容器。历史记录应用的历史信息日志、指标、诊断信息会被转移到JobHistoryServer如果配置了进行长期存储供后续审计和分析。RM本地的应用记录会被清理以释放内存。4. 高可用与容错机制实战对于生产环境ResourceManager本身不能是单点故障。YARN通过Active/Standby架构实现了RM的高可用。4.1 基于ZooKeeper的自动故障转移架构部署两个或多个RM实例一个为Active其余为Standby。它们共享一个持久化的状态存储通常是ZooKeeper。Leader选举所有RM实例启动时都会尝试在ZooKeeper的某个znode如/yarn-leader-election上创建临时节点。成功创建者成为Active RM。状态同步Active RM将所有状态变更新应用、节点状态更新等同时写入状态存储和自身的内存。Standby RM会实时地从状态存储中读取这些变更并重放到自己的内存中从而保持与Active RM近乎一致的状态视图。这个过程称为“状态重演”。故障检测与切换ZooKeeper的临时节点特性保证了当Active RM进程崩溃或网络分区时其创建的znode会自动消失。Standby RM监听到这一变化会立即触发新的Leader选举其中一个Standby成功当选为新的Active。恢复与接管新Active RM从状态存储中加载最新的持久化状态完成初始化。然后它开始接收NM的心跳。NM在发现心跳响应异常或超时后会向RM地址列表中的下一个地址重试从而连接到新的Active RM并重新注册。运行中的AM也会在下次向RM心跳时发现连接断开并尝试向新的RM重新注册。4.2 配置要点与避坑指南配置YARN RM HA涉及多个关键参数一个配置不当就可能导致脑裂或数据不一致。# core-site.xml property nameha.zookeeper.quorum/name valuezk1:2181,zk2:2181,zk3:2181/value /property # yarn-site.xml property nameyarn.resourcemanager.ha.enabled/name valuetrue/value /property property nameyarn.resourcemanager.ha.rm-ids/name valuerm1,rm2/value /property property nameyarn.resourcemanager.hostname.rm1/name valuehostname1/value /property property nameyarn.resourcemanager.hostname.rm2/name valuehostname2/value /property property nameyarn.resourcemanager.zk-address/name valuezk1:2181,zk2:2181,zk3:2181/value /property property nameyarn.resourcemanager.ha.automatic-failover.enabled/name valuetrue/value /property property nameyarn.resourcemanager.ha.automatic-failover.embedded/name valuetrue/value /property property nameyarn.resourcemanager.store.class/name valueorg.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore/value /property高可用配置核心陷阱ZK连接字符串ha.zookeeper.quorum和yarn.resourcemanager.zk-address必须配置且一致。我曾遇到过因为漏配后者导致Standby RM无法同步状态的问题。主机名解析yarn.resourcemanager.hostname.rmX配置的主机名必须在所有NM节点和客户端节点的/etc/hosts文件或DNS中能够正确解析到对应的IP地址。否则NM心跳和客户端提交会失败。防火墙确保所有RM节点、NM节点、ZK节点之间的相关端口如RM的8032、8088ZK的2181、2888、3888是互通的。脑裂预防依赖于ZooKeeper的临时节点机制基本可以避免脑裂。但要确保ZK集群本身的稳定性和奇数台部署。4.3 故障切换演练与监控纸上谈兵不如一次实战演练。定期进行RM故障切换演练至关重要。优雅切换可以通过yarn rmadmin -transitionToStandby和yarn rmadmin -transitionToActive命令手动切换Active/Standby状态测试命令是否生效。暴力故障模拟直接kill -9掉Active RM的进程。观察Standby RM的日志看是否成功选举为Active。NM的日志看是否在短暂心跳失败后重新连接到新的RM。运行中应用的AM日志看是否成功重新注册。客户端通过yarn application -status命令查询应用状态是否正常。监控指标将RM的JMX指标如YarnResourceManager的Active状态、NumActiveNMs、AppsSubmitted等接入PrometheusGrafana。设置告警规则当Active RM失联或NM大量断开时及时报警。5. 性能调优与运维实战一个配置得当的ResourceManager是集群稳定的基石。以下是一些关键的调优参数和运维经验。5.1 内存与JVM调优ResourceManager作为Java进程其JVM堆内存设置直接影响其能管理的集群规模。yarn.resourcemanager.scheduler.class选择正确的调度器。yarn.scheduler.minimum-allocation-mb/-vcores资源调度的最小单位。设置过大会导致小任务浪费资源过小会增加调度开销。通常内存设为1GB或512MBvCore设为1。yarn.scheduler.maximum-allocation-mb/-vcores单个容器能申请的最大资源。必须大于或等于你最大的任务需求。yarn.resourcemanager.resource-tracker.client.thread-count处理NM心跳的RPC服务器线程数。在大集群1000节点中需要调大此值如默认50可调至200以避免心跳处理瓶颈。yarn.resourcemanager.scheduler.client.thread-count处理AM资源请求的线程数同样需要根据AM数量调整。JVM堆内存通过YARN_RESOURCEMANAGER_OPTS设置。对于管理数千节点、数万应用的大集群堆内存可能需要设置到-Xmx16g甚至更高。同时开启GC日志分析Full GC频率。5.2 调度器队列配置实战以Capacity Scheduler为例一个良好的队列规划是高效管理的基础。!-- capacity-scheduler.xml -- configuration property nameyarn.scheduler.capacity.root.queues/name valueprod,dev,research/value /property property nameyarn.scheduler.capacity.root.prod.capacity/name value50/value /property property nameyarn.scheduler.capacity.root.dev.capacity/name value30/value /property property nameyarn.scheduler.capacity.root.research.capacity/name value20/value /property !-- 允许借用资源 -- property nameyarn.scheduler.capacity.root.prod.user-limit-factor/name value1/value /property property nameyarn.scheduler.capacity.root.prod.maximum-capacity/name value100/value /property !-- 设置队列管理员 -- property nameyarn.scheduler.capacity.root.prod.acl_administer_queue/name valueprod_admin_group/value /property /configuration队列设计经验容量分配根据业务重要性分配。生产队列prod保证高优先级任务的资源开发队列dev和研发队列research共享剩余资源。弹性设置maximum-capacity设置为100user-limit-factor设置为1意味着该队列在需要时可以占用集群全部资源但其他队列需要资源时会被抢占回来。这是保证利用率的关键。ACL控制一定要配置队列的ACL防止普通用户向生产队列乱提交作业或者误杀他人的重要任务。5.3 节点标签与资源隔离在异构集群中比如混布了CPU密集型和高内存型机器可以使用节点标签将节点分区。打标签给特定NM节点打上标签如high-mem。yarn rmadmin -addToClusterNodeLabels high-mem yarn rmadmin -replaceLabelsOnNode node-hostname:porthigh-mem队列访问标签配置只有特定队列可以访问带标签的节点。property nameyarn.scheduler.capacity.root.research.accessible-node-labels/name valuehigh-mem/value /property property nameyarn.scheduler.capacity.root.research.accessible-node-labels.high-mem.capacity/name value100/value /property应用指定标签提交应用时通过-Dmapreduce.job.node-label-expressionhigh-mem指定任务需要运行在high-mem标签的节点上。这样内存密集型任务如Spark就能被精确调度到高内存节点避免与CPU密集型任务争抢资源。5.4 日常运维与问题排查常见问题1应用提交后一直卡在ACCEPTED状态可能原因调度器队列资源已满且没有配置资源抢占或者AM容器资源请求过大没有节点能满足。排查检查RM Web UI的调度器页面看目标队列的已用/可用资源。检查AM容器请求的资源量是否超过节点的最大可分配资源yarn.nodemanager.resource.memory-mb。常见问题2NodeManager节点状态为UNHEALTHY可能原因NM本地磁盘健康检查失败默认检查yarn.nodemanager.local-dirs和yarn.nodemanager.log-dirs的可用空间低于阈值yarn.nodemanager.disk-health-checker.min-healthy-disks则标记不健康。排查登录该NM节点检查本地磁盘空间清理日志或临时文件。查看NM日志中的健康检查详情。常见问题3ResourceManager GC频繁响应变慢可能原因堆内存不足或存在内存泄漏如长时间运行后已完成的应用上下文未及时清理。排查开启RM的GC日志分析GC频率和时长。检查yarn.resourcemanager.max-completed-applications配置该值控制RM内存中保留的最大已完成应用数量默认1000如果应用提交极其频繁可以适当调低或确保有JobHistoryServer来接管历史记录。运维习惯定期清理定期清理HDFS上过期的作业历史日志/tmp/hadoop-yarn/staging和NM本地目录防止磁盘撑爆。监控关键指标除了资源使用率更要关注AppsPending等待调度的应用数、ContainersPending等待分配的资源容器数、RM的RPC队列长度和平均处理时间。这些是集群是否过载的先行指标。版本升级升级Hadoop/YARN版本时要特别注意状态存储格式的兼容性。从旧版本恢复状态到新版本RM前务必先在测试环境验证。ResourceManager的深度调优和稳定运维是一个持续的过程需要结合具体的业务负载和硬件环境不断观察和调整。理解其内部组件的协作机制是进行有效管理和故障排查的根本。当你再看到yarn application命令输出的复杂状态或是Web UI上跳动的各项指标时希望你能清晰地知道背后是哪个组件在发挥作用以及如何去影响它。