首页 / 资讯中心 / 文章详情

YARN容量调度器多队列配置实战:资源隔离与弹性调度

YARN容量调度器多队列配置实战:资源隔离与弹性调度 ★ FEATURED ARTICLE
1. 从单队列到多队列为什么容量调度器需要多队列配置刚接触Hadoop那会儿我图省事整个集群就配了一个default队列所有任务往里扔谁抢到算谁的。小规模测试倒也没出过什么大问题可一旦任务量上来麻烦就来了——一个跑批任务把资源全占了后面提交的交互式查询只能干等着运维那边电话一个接一个。后来被逼着去啃YARN的调度器配置才发现容量调度器Capacity Scheduler的多队列机制才是解决这类资源争抢的正解。容量调度器是YARN里最常用的调度器之一它的核心思路是把整个集群的资源切分成多个队列每个队列拿到一个保证容量capacity同时允许在资源空闲时借用其他队列的闲置资源。这个设计的好处很直接关键业务有保底资源不会被其他任务饿死非关键业务在空闲时段又能充分利用集群不至于让机器闲着。说白了就是“保底弹性”的组合拳。多队列配置要解决的问题本质上就是资源隔离与共享的平衡。你既不想让某个业务把集群吃干抹净又不想让资源白白浪费。容量调度器通过队列层级、容量比例、最大容量上限、用户限制等一整套参数把这件平衡的事做细了。适合谁来参考我觉得三类人最需要一是刚接手Hadoop集群、发现资源分配一团糟的运维二是需要给不同团队或业务线划分资源的平台开发者三是想搞明白YARN调度底层逻辑、准备调优的大数据工程师。下面我就按实际配置的顺序把多队列这套东西拆开讲透。2. 容量调度器的核心概念与多队列设计思路2.1 队列层级与资源分配的基本逻辑容量调度器支持树形队列结构也就是队列下面还能挂子队列。这个设计不是摆设它对应的是真实组织架构里的资源划分方式。比如一个公司有数据平台部和算法部数据平台部下又分实时计算组和离线计算组那队列就可以配成root下面挂data_platform和algorithmdata_platform下面再挂realtime和batch。资源从根队列往下逐层分配每一层都有自己的容量比例。这里有个关键点容易搞混容量capacity是保证值不是上限值。假设root总资源是100个虚拟核队列A的capacity配了30%那A至少能拿到30个核。但如果队列B只用了10%A在需要的时候可以借走B闲置的部分实际使用可能超过30%。真正限制A不能无限膨胀的是最大容量maximum-capacity这个参数才是硬上限。我见过不少配置把这两个概念弄反结果要么资源借不出去要么某个队列把集群占满。资源分配还有一层层级公平的考量。当多个队列同时缺资源时调度器会按容量比例来分配而不是先到先得。比如A和B的capacity都是50%同时有任务在等那资源就五五开。但如果A已经用了60%B只用了40%新释放的资源会优先给B直到两者回到比例平衡。这个机制保证了长期来看各队列拿到的资源趋近于配置比例。2.2 为什么选择容量调度器而不是公平调度器YARN里另一个常见选择是公平调度器Fair Scheduler两者都能做多队列但设计哲学不同。公平调度器的核心是“动态平衡”它追求的是任意时刻各队列资源占比接近配置权重谁的资源少就优先给谁。容量调度器则更强调“保证容量”先确保每个队列拿到承诺的那份再谈借用。选哪个取决于业务场景。如果集群里跑的都是同优先级任务追求整体吞吐和响应速度公平调度器可能更合适。但如果有明确的业务分级——比如核心报表任务必须按时完成测试任务可以慢慢跑——那容量调度器的保底机制就更对路。我实际维护的集群里核心业务队列的capacity配得比较高maximum-capacity设成100%保证高峰期能吃掉空闲资源测试队列capacity低但maximum-capacity也放开闲时能跑满。这种“核心保底、边缘弹性”的玩法容量调度器支持得最自然。还有一个实际因素是配置的直观性。容量调度器的参数命名和层级结构比较贴近运维的思维习惯capacity、maximum-capacity、user-limit-factor这些参数一看就大概知道干什么。公平调度器的配置相对更灵活但也更绕。对于刚上手YARN调度的团队容量调度器的学习曲线更平缓。2.3 多队列配置要提前想清楚的几件事动手写配置文件之前有几件事必须先想明白否则配出来的队列大概率要返工。第一是队列数量和层级深度。队列不是越多越好每多一层就多一层调度开销而且层级太深之后资源碎片化严重大任务反而不好调度。我的经验是控制在三层以内最底层队列数量别超过十个。如果业务线特别多可以考虑用队列名做逻辑区分而不是无限加层级。第二是容量比例的分配依据。这个不能拍脑袋得看历史资源使用数据。我一般会拉过去一个月的YARN资源监控算各业务线的平均使用量和峰值使用量再结合未来规划来定capacity。保证容量要覆盖平均使用量maximum-capacity要能容纳峰值这样既不会平时浪费也不会高峰期卡死。第三是用户和应用的限制策略。多队列解决了队列间的隔离但队列内部如果某个用户提交大量任务照样能把队列占满。这时候就需要user-limit-factor和maximum-am-resource-percent这类参数来兜底。user-limit-factor控制单个用户最多能用队列容量的几倍默认是1意思是不能超过队列保证容量。如果队列内部用户比较多可以适当调大但别超过2否则隔离就形同虚设了。3. 多队列配置实操从capacity-scheduler.xml开始3.1 配置文件结构与关键参数逐项解读容量调度器的配置集中在capacity-scheduler.xml这个文件里放在Hadoop配置目录下。它的参数命名有一套固定规则yarn.scheduler.capacity.是前缀后面跟队列路径和参数名。根队列用root表示子队列用点号连接比如root.data_platform.realtime。先看几个全局参数。yarn.scheduler.capacity.root.queues定义根队列下有哪些子队列多个队列用逗号分隔。yarn.scheduler.capacity.root.capacity是根队列的容量固定为100。yarn.scheduler.capacity.maximum-am-resource-percent控制ApplicationMaster能占用的最大资源比例默认0.1意思是10%的资源留给AM剩下的给实际任务。这个值在小集群里可以调小大集群里可以适当调大但一般不超过0.2。队列级别的参数里capacity和maximum-capacity是最核心的两个。capacity是保证容量所有同级队列的capacity之和必须等于100。maximum-capacity是资源使用上限可以等于100表示允许借用所有空闲资源。还有一个user-limit-factor控制单用户资源上限相对于队列capacity的倍数。maximum-am-resource-percent可以在队列级别覆盖全局值控制该队列的AM资源占比。资源分配还涉及资源计算器的选择。默认是DefaultResourceCalculator只考虑内存如果要用CPU资源做调度得换成DominantResourceCalculator。这个选择影响capacity的计算方式配之前要确认集群的资源类型。3.2 一个三层队列结构的完整配置示例假设有个集群总资源是200GB内存、100个虚拟核。业务分两大块数据平台和算法。数据平台下面再分实时和离线算法下面分训练和推理。配置目标是这样数据平台整体保证40%资源最高可用70%算法整体保证60%资源最高可用100%数据平台内部实时和离线各占一半保证容量算法内部训练占70%推理占30%对应的capacity-scheduler.xml配置如下configuration property nameyarn.scheduler.capacity.root.queues/name valuedata_platform,algorithm/value /property property nameyarn.scheduler.capacity.root.data_platform.capacity/name value40/value /property property nameyarn.scheduler.capacity.root.data_platform.maximum-capacity/name value70/value /property property nameyarn.scheduler.capacity.root.data_platform.queues/name valuerealtime,batch/value /property property nameyarn.scheduler.capacity.root.data_platform.realtime.capacity/name value50/value /property property nameyarn.scheduler.capacity.root.data_platform.realtime.maximum-capacity/name value100/value /property property nameyarn.scheduler.capacity.root.data_platform.batch.capacity/name value50/value /property property nameyarn.scheduler.capacity.root.data_platform.batch.maximum-capacity/name value100/value /property property nameyarn.scheduler.capacity.root.algorithm.capacity/name value60/value /property property nameyarn.scheduler.capacity.root.algorithm.maximum-capacity/name value100/value /property property nameyarn.scheduler.capacity.root.algorithm.queues/name valuetraining,inference/value /property property nameyarn.scheduler.capacity.root.algorithm.training.capacity/name value70/value /property property nameyarn.scheduler.capacity.root.algorithm.training.maximum-capacity/name value100/value /property property nameyarn.scheduler.capacity.root.algorithm.inference.capacity/name value30/value /property property nameyarn.scheduler.capacity.root.algorithm.inference.maximum-capacity/name value100/value /property property nameyarn.scheduler.capacity.maximum-am-resource-percent/name value0.15/value /property property nameyarn.scheduler.capacity.resource-calculator/name valueorg.apache.hadoop.yarn.util.resource.DominantResourceCalculator/value /property /configuration这里有几个细节值得说。子队列的capacity是相对于父队列的不是相对于整个集群。比如realtime的50%是data_platform那40%里的一半实际占集群20%。maximum-capacity同理是相对于父队列的上限。另外所有叶子队列的capacity之和必须等于100中间层队列的capacity之和也要等于100这个校验在启动时会做配错了直接起不来。3.3 配置生效与队列状态验证改完配置文件后需要重启ResourceManager或者用yarn rmadmin -refreshQueues做热刷新。热刷新不用重启集群但有些参数改不了比如队列的增删。我一般先在测试环境验证确认没问题再上生产。验证队列是否生效有几个命令很实用。yarn queue -status 队列名能看队列的当前状态包括容量、已用资源、运行中应用数。yarn application -list -appStates ALL可以看所有应用跑在哪个队列。ResourceManager的Web UI里有个Scheduler页面能直观看到各队列的资源占用和容量比例排查问题的时候我基本都开着这个页面。还有一个容易忽略的点队列的ACL配置。默认情况下所有用户都能往任何队列提交任务这显然不安全。通过yarn.scheduler.capacity.root.队列名.acl_submit_applications可以限制哪些用户或组能往该队列提交任务。格式是用户1,用户2 组1,组2中间用空格分隔用户和组。这个配置在多团队共享集群时几乎是必须的否则隔离就只是纸面上的。4. 多队列运行中的典型问题与排查实录4.1 队列资源借出去了收不回来怎么办这是容量调度器多队列配置里最常见的问题。现象是某个队列平时用不满资源被其他队列借走等它自己需要资源时借出去的部分迟迟不释放导致任务排队。根本原因在于容量调度器不会强制抢占它只能等借用的队列自己释放资源。解决思路有几个。最直接的是配置抢占策略。YARN支持在容量调度器上开启抢占通过yarn.scheduler.capacity.队列路径.disable_preemption设为false来启用。抢占的触发条件是某个队列的资源使用低于其保证容量一定时间调度器会杀掉其他队列里低优先级的Container来释放资源。抢占有代价被杀的Container对应的任务要重跑所以一般只对核心队列开启且设置合理的抢占等待时间。另一个思路是调整maximum-capacity。如果某个队列经常借走大量资源不还可以适当降低它的maximum-capacity限制它能借的上限。比如把测试队列的maximum-capacity从100降到60它最多只能用到60%的资源剩下的留给其他队列。这个调整比较温和不会杀任务但会牺牲一些资源利用率。还有一个实操技巧是用队列优先级配合。容量调度器支持队列优先级高优先级队列在资源分配时有优势。把核心业务队列的优先级调高即使资源被借走新任务提交时也能更快拿到资源。优先级通过yarn.scheduler.capacity.root.队列名.priority配置数值越小优先级越高。4.2 队列容量之和超100导致的启动失败这个坑我踩过不止一次。容量调度器在启动时会校验同级队列的capacity之和是否等于100不等于就直接抛异常ResourceManager起不来。报错信息一般是“Sum of capacities of child queues is not 100”。问题往往出在层级计算上。比如root下面有两个队列A和BA的capacity是40B是60加起来100没问题。但A下面又挂了A1和A2如果A1配30、A2配30加起来60不等于100就会报错。子队列的capacity之和必须等于100跟父队列的capacity是多少无关。这个规则容易记混配的时候要逐层检查。还有一种情况是动态增删队列。热刷新不支持增删队列只能改已有队列的参数。如果要加新队列必须改配置文件后重启ResourceManager。重启前一定要确认所有同级队列的capacity之和是100否则重启会失败集群直接不可用。我的习惯是改完配置先用hadoop org.apache.hadoop.yarn.conf.YarnConfiguration之类的工具做一次配置校验或者直接在测试环境重启验证。4.3 单用户占满队列的排查与限制队列内部如果某个用户提交了大量任务把队列资源占满其他用户就提交不进去了。这个问题在多团队共享队列时特别突出。排查方法很简单在ResourceManager Web UI的Scheduler页面看队列的User Limit信息或者用yarn queue -status看各用户的资源使用。限制手段主要是user-limit-factor。这个参数控制单个用户最多能用队列capacity的几倍。默认是1意思是用户最多用到队列的保证容量。如果队列capacity是40%那单用户最多用40%的集群资源。调大到2单用户最多能用80%。这个值不能设太大否则队列隔离就没意义了。我一般设1.5到2之间既给用户一些弹性又不至于让一个人吃掉整个队列。还有一个参数是minimum-user-limit-percent它保证每个用户至少能拿到队列资源的某个百分比。比如设成10意思是队列里至少有10个用户能同时使用资源每个用户至少10%。这个参数在用户数不确定的场景下有用能防止先到的用户把资源占完。实际配置时user-limit-factor和minimum-user-limit-percent要配合使用前者管上限后者管下限。4.4 常见问题速查表问题现象可能原因排查方法解决措施ResourceManager启动失败报容量之和不等于100同级队列capacity之和不等于100检查配置文件各层级capacity之和调整capacity使同级之和为100队列资源被借走不释放容量调度器不强制抢占查看队列资源使用和保证容量对比开启抢占或降低借用队列maximum-capacity单用户占满队列user-limit-factor过大或未配置Web UI查看用户资源使用调小user-limit-factor配置minimum-user-limit-percent任务提交报队列不存在队列未配置或ACL限制检查队列配置和ACL添加队列配置或调整ACL热刷新后配置未生效部分参数不支持热刷新查看ResourceManager日志重启ResourceManagerAM资源占比过高导致任务排队maximum-am-resource-percent过大查看AM资源占用调小该参数一般0.1到0.155. 多队列配置的调优经验与长期维护建议5.1 容量比例怎么定才合理容量比例的设定没有标准答案但有几个原则可以参考。保证容量覆盖平均使用量这是底线。如果某个队列的平均使用量是集群的25%那capacity至少配25%否则平时就会经常触发借用调度开销大。maximum-capacity覆盖峰值使用量但不要轻易设100%除非这个队列确实需要弹性到全集群。我一般把核心队列的maximum-capacity设成80到90留一些余量给其他队列应急。比例调整要有数据支撑。我每个月会拉一次YARN的资源使用报表看各队列的实际使用率和排队情况。如果某个队列长期使用率低于capacity说明配高了可以往下调如果经常触发maximum-capacity限制说明配低了需要往上调。调整前先在测试环境验证确认不会导致其他队列资源不足。还有一个经验是留一个弹性队列。不管业务怎么划分我都会留一个capacity不高但maximum-capacity全开的队列专门给临时任务和测试用。这个队列平时不怎么占资源但需要的时候能借用空闲资源不至于让临时任务没地方跑。5.2 监控与告警要盯哪些指标多队列跑起来之后监控跟不上就是睁眼瞎。我重点盯几个指标各队列的资源使用率包括已用内存、已用vcore、运行中应用数队列的排队应用数排队数持续大于零说明资源不足AM资源占比超过配置的maximum-am-resource-percent就要注意抢占次数如果抢占频繁发生说明容量配置可能不合理。告警阈值我一般这样设队列使用率持续10分钟超过maximum-capacity的90%就告警排队应用数超过5个告警抢占次数每小时超过3次告警。这些阈值可以根据集群规模和业务敏感度调整。监控工具用Prometheus加Grafana就能搭起来YARN的Metrics接口暴露了这些数据。5.3 队列调整的时机与操作节奏队列配置不是配一次就完事业务在变队列也要跟着调。但调整不能太频繁否则调度器刚适应又变了反而影响稳定性。我的节奏是季度做一次大调整月度做一次小调整。大调整涉及队列增删和容量比例重分配需要走变更流程在业务低峰期操作。小调整只改个别参数比如user-limit-factor或maximum-am-resource-percent可以热刷新影响面小。调整前一定要备份配置文件并且记录调整前后的参数对比。出问题的时候能快速回滚。调整后观察至少一个完整业务周期确认没有异常再做下一次调整。我见过有人一天改三次配置结果调度器行为混乱任务排队反而更严重。5.4 几个容易忽略的细节最后分享几个实操中容易忽略但影响不小的细节。队列名称不要用中文或特殊字符虽然配置上可能支持但Web UI和命令行工具显示会有问题排查时很麻烦。队列的ACL要定期审查人员变动后及时调整避免离职人员还能提交任务。配置文件的版本管理要做好每次变更都提交到版本库方便追溯。还有一个细节是资源计算器的选择要和集群资源类型匹配。如果集群只关心内存用默认的DefaultResourceCalculator就行如果CPU也是瓶颈一定要换成DominantResourceCalculator否则CPU被某个队列吃满内存还有富余调度器却认为资源充足继续往那个队列派任务。这个坑我在一个CPU密集型集群里踩过换了计算器之后问题才解决。容量调度器的多队列配置说到底是在资源隔离和利用效率之间找平衡。配得太死资源浪费配得太松隔离失效。我的体会是先按业务重要性划出大框架再用监控数据慢慢微调别指望一次配到完美。跑上几个月积累一些实际数据调整起来就有方向了。
阅读完成 · 觉得有帮助?
咨询建站