想象一下,你所在的科技园区新开了一家大型食堂。园区里有十几家公司,几千名员工,食堂却只有 8 个打饭窗口。每到饭点,各个窗口前都排起长队——有人急着吃完饭回去开会,有人只是想来蹭碗汤,还有几个大部门恨不得把整排窗口都包下来。这时候,食堂经理就得定规矩:谁先打饭?每个部门最多占几个窗口?排队太久的人能不能插队? GPU 集群的调度,和食堂打饭几乎是同一套逻辑。在一家公司的 GPU 集群里,可能有十几个团队共享几百块显卡:算法工程师要跑训练、数据团队要做批处理、线上推理服务一刻不能停。计算资源有限,需求却永远旺盛,所以需要一套“排队规则”来分配资源。这就是队列(Queue)与优先级(Priority)调度干的事——队列是排队的队伍,优先级是加急餐券,权重是各窗口蒸锅的大小,配额则是每桌限点的菜数。 这篇文章就带你以食堂经理的视角,把 GPU 集群中的队列、优先级、权重、配额、多租户治理、效果评估和配置实践一次讲明白。读完你就能理解:如何让重要任务“插队”的同时不饿死小团队,如何让 100 块 GPU 养活 500 个跑任务的工程师。
掌握队列与优先级调度,你就拥有了 GPU 集群资源分配的“指挥棒”——既能保证核心业务优先,又能让集群利用率拉满,这是每位 AI 平台工程师的必修课。
可视化演示
展示GPU集群多租户权重队列设计、优先级计算与抢占式调度机制及Slurm与K8s调度流程对比,通过交互切换三种模式理解集群资源调度策略。
本节配有交互动效(进入视口后自动加载,约 3KB)。
权重队列与多租户 Q1(w=0.5): 高权重队列分配50%GPU资源 Q2(w=0.3)+Q3(w=0.2)按权重公平分享 allocation_i = total_gpu × weight_i 多租户通过权重队列实现资源分区隔离
队列基础概念
食堂开门迎客,第一件事就是立起几个窗口:套餐窗口、面食窗口、清真窗口。每个窗口前拉一条隔离带,员工按顺序排队,后来的人自动站到队尾。GPU 集群里的队列(Queue)也是同样的东西——它是一个作业等待区的名称。当一位工程师提交一个训练任务,调度器不会立刻分配 GPU,而是把任务放进某个队列里排队。队列本质上就是一个有序的作业集合,调度器从队首依次取出作业,分配给空闲的 GPU。
为什么要分多条队列而不是一个大队?因为不同的业务有不同的诉求:在线推理要秒级响应,离线训练等半小时无所谓,数据预处理则只在深夜跑。如果所有任务混在一个大队里,一个跑 3 天的训练任务会堵住所有想插进来的小任务。所以集群管理员会按照业务类型、团队归属、GPU 型号划分多个队列,每个队列拥有独立的排队空间和调度参数。
队列和作业的绑定关系,决定了任务去哪里排队。在 Slurm 中,提交作业时用 -p partition 指定分区名;在 Kubernetes 中,则通过 namespace 或调度器配置把 Pod 归入某个队列。可以理解为食堂每个窗口上方挂着的LED屏:你的任务属于哪个团队、需要哪种卡型,就自动去对应窗口排队。默认情况下,队列内部按FIFO(先进先出)的顺序服务,先提交的作业先拿卡。
有了队列,调度就有了“秩序”。没有队列的集群就像没有隔离带的食堂,所有人挤在窗口前,谁也吃不上饭。队列的存在,让每个任务都知道自己在队伍中的位置,也让管理员能针对不同窗口制定不同的服务策略。
- 队列符号定义用集合符号表示一个队列,里面装着 n 个等待调度的任务,下标越大表示越晚到达。
- 队首任务$T_1$ 是队首任务,也就是最早提交、下一个将被调度的任务。
- 队尾任务$T_n$ 是队尾任务,新提交的作业会追加到它后面。
优先级机制
排队的队伍有了,但问题来了:食堂经理时不时会收到“加急订单”——某位核心客户的模型要上线,必须在 10 分钟内跑完推理验证;或者某个训练任务已经等了一个小时,再等下去项目就延期了。这时候,光靠“先来后到”就不够了。于是食堂推出了加急餐券:持有急事券的员工可以走到队伍最前面,甚至可以把正在窗口打饭的人劝回去,让对方稍后再来。
在 GPU 集群里,这个“加急餐券”就是优先级(Priority)。每个任务提交时都会携带一个优先级数值,调度器在决定“下一个谁上车”时,首先比较优先级。优先级通常由几个因素共同决定:用户提交时显式指定(比如用 --priority=high)、任务的等待时长(等得越久,优先级自动增长,防止饿死)、以及业务紧急度策略(管理员为某些关键业务设置的基础优先级)。
优先级比较的规则要牢记:数值越小,优先级越高。这就好比餐券上印的等级,1 级是最高级,3 级排最后。当两个任务的优先级相同时,再按 FIFO 的先后顺序排队。更复杂的情况是抢占(Preemption)——当集群没有空闲 GPU,而一个高优任务急需执行时,调度器会把正在运行的低优任务“请出”窗口,让高优任务立即上车。被抢占的任务不会丢失,而是回到队列前端等待,下次有机会继续跑。
优先级机制就像食堂的加急通道,它让“重要且紧急”的任务能插队,但绝不是无限特权——如果加急的任务太多,调度器依然要兼顾其他队伍。优先级解决了“谁先吃”的问题,但还没回答“每家能吃多少”的问题,后者要交给权重机制。
- 基础优先级管理员或用户为任务设定的初始优先级,数值越小越优先。
- 等待增益任务在队列中等待的时间越长,这个增量越大,让老任务逐渐“插队”。
- 总优先级两者相加得到调度器用来排序的最终分数。
加权公平调度
想象食堂有三个大蒸锅,经理定了个规矩:套餐窗口有 3 个蒸锅,面食窗口 2 个,清真窗口 1 个。每个窗口每批蒸出来的馒头数固定,窗口前排队的人越多,每个人分到的就越少。但蒸锅不是“专属”的——如果面食窗口没人排队,套餐窗口可以借用它的蒸锅多蒸几笼。这就是加权公平调度(Weighted Fair Scheduling)的核心思想。
在 GPU 集群中,权重(Weight)决定了每个队列在“同时有需求”时能分到的资源比例。假设高优队列权重 3、普通队列权重 2、低优队列权重 1,总权重是 6。那么当所有队列都有任务排队时,高优队列获得集群资源的 3/6(50%),普通队列获得 2/6(约 33%),低优队列获得 1/6(约 17%)。这与“按人头分配”不同,权重高的队列在竞争中的话语权更大。
加权公平调度还有个重要特性:空闲资源的弹性复用。如果高优队列暂时没有任务,它的份额不会空着浪费,而是自动让给其他有任务的队列使用。这保证了集群利用率始终很高。同时,调度器还有一个防饿机制(Anti-starvation)——即使低权重的队列,也保证它能得到“最少一份”资源,不至于因为权重太低而永远等不到调度。
回到食堂,蒸锅的比喻完美诠释了权重:它保证“大部门”在高峰时段能吃到更多,但也留了小灶给“小部门”,不至于让人饿肚子。不过,权重管的是“相对比例”,如果某个团队野心太大,提交 10 倍于份额的任务,整个食堂都会被它挤爆。这时候就需要配额来设一道“绝对上限”。
- 队列编号与权重假设集群有 n 个队列,第 i 个队列的权重记为 $w_i$,权重由管理员根据业务重要性设定。
- 权重总和分母是所有队列权重之和,它把权重归一化成“占比”。
- 权重比例第 i 个队列的权重占全体权重的比例,这个比例在 0 到 1 之间。
- 乘上总资源用这个比例乘以集群可调度的总资源量 $R_{total}$,就得到该队列理论上可获得的资源份额。
资源配额管理
食堂可以给每个窗口规定“每桌每次最多打几份菜”吗?自助餐是可以的——经理在取餐台立了块牌子:每家公司每天最多消耗 200 份套餐,其中早餐最多 50 份。这就是配额(Quota)。它跟权重不同,权重管的是“份额比例”,配额管的是“绝对数量上限”。在 GPU 集群里,配额通常这样定义:每个团队最多同时使用多少块 GPU、多少 GB 显存、多少 CPU 核数。
配额有两个关键数值:最小保证(min)和最大上限(max)。最小保证意味着,只要集群资源足够,调度器优先满足这个底线——就像食堂承诺每家公司至少能订到 20 份午饭;最大上限则意味着,即使集群有空闲资源,你的团队也不能超过这个数——防止某个团队囤积资源搞“独占”。实际使用量在最小保证和最大上限之间动态浮动。
配额的设置有个反直觉的技巧:所有配额的总和可以大于物理资源总量。比如集群只有 100 块 GPU,但三个团队各配了 60 块的配额上限,加起来 180。这在工程上叫“超卖”(overcommit)。为什么不直接设成 100?因为大部分团队不会同时把配额打满,利用率的低谷期可以共享。当任务请求超过配额上限时,调度器可以选择让任务排队等待其他任务释放资源,或者直接拒绝并提示用户。
配额就像自助餐的“限取量”牌子,它让每个团队都清楚自己的边界。权重负责“公平地分蛋糕”,配额负责“防止一个人把蛋糕全拿走”。两者配合,再加上优先级决定“先切哪块”,多租户的食堂才算有了完整的规矩。
- 最小保证配额调度器承诺为该团队保留的资源量,只要集群有资源就优先满足。
- 实际使用量当前该团队正在占用的 GPU 数量,它随着任务提交和结束而动态变化。
- 最大上限配额该团队在任何时刻都不得超过的资源量,超过后新任务只能排队。
多租户治理
园区食堂不只是服务一家公司,而是十几家公司共用的。每家公司的员工饭卡不同,但都在同一个食堂就餐。这时候管理就复杂了:A 公司包的机房(啊不,包场)不能让人乱进,但 B 公司临时人多,能不能借 A 公司的空桌子?这就是多租户治理要解决的问题——多个团队(租户)共享同一个 GPU 集群,既要相互隔离,又要灵活共享。
租户隔离是第一道防线。每个租户拥有自己独立的命名空间(namespace),里面运行的作业、配置的配额、创建的密钥互不可见。在 Kubernetes 中,namespace 天然成为资源配额的作用域;在 Slurm 中,则通过 partition 和账号(account)来隔离。隔离的意义在于:A 团队的错误配置不会影响 B 团队,一个租户的异常流量也不能挤占别人的资源。
隔离之后是共享策略。完全隔离的集群利用率极低——A 团队周末不上班,GPU 全部闲置,B 团队却排队到深夜。所以调度器需要支持“弹性共享”:各租户的预留配额加上一个共享资源池,总资源等于二者之和。当某租户的预留配额用不完时,剩余部分自动流入共享池,供其他租户临时借用;一旦该租户有新任务提交,借出去的资源会被逐步收回。
多租户治理的精髓,是“隔离但不孤立”。隔离保证了安全与稳定,共享保证了效率与弹性。我们的食堂既能容纳十几家公司,又不让某家公司把食堂变成自家餐厅——这正是 GPU 集群管理员最想达到的境界。但规则定了,怎么知道定得好不好?要看实际效果。
- 租户数量集群中一共有 M 个租户(团队、部门、项目组),每个租户都有自己的预留配额。
- 各租户配额求和把所有租户的预留配额加起来,这是“保底”的分配部分。
- 共享资源池管理员特意保留的公共资源,供各租户在高峰期临时借用。
- 总资源分解集群所有物理资源恰好分成“租户预留”和“共享池”两部分。
策略效果评估
食堂经理折腾了这么多规矩,总得有个数据来衡量:员工平均排队多久?窗口的翻台率(利用效率)怎么样?如果排队时间太长,说明资源不够或调度不合理;如果窗口经常空着,说明规则太死板、资源浪费。GPU 集群的调度策略同样需要量化评估,主要看两个核心指标:排队时间和集群利用率。
排队时间(Waiting Time)指任务从提交到真正开始执行的时间间隔。它是调度公平性最直观的体现——如果低优任务的平均排队时间是高优任务的 10 倍,说明优先级权重设置得太激进;如果所有任务都在排长队,说明集群容量不足以支撑当前负载。管理员通常会统计每个队列的 p50/p95 排队时间,用来发现“堵点”。
集群利用率(Utilization)则反映资源的整体忙碌程度,包括 GPU 平均利用率、节点分配率、空闲资源比例等。这里有个微妙的权衡:排队论告诉我们,当系统利用率接近 100% 时,平均等待时间会急剧上升。好比食堂上座率 95% 时,队伍会排到门口;上座率 80% 时,几乎随到随吃。因此,成熟的集群通常会保留 10%~20% 的冗余,用适度空闲换取低延迟响应。
看到这个公式,食堂经理就能理解:为什么不能把窗口排得满满当当——一旦利用率逼近 100%,队伍会呈指数级恶化。好的调度策略,是在“想尽办法提高利用率”和“保证排队时间可接受”之间找平衡。现在理论和指标都有了,最后一节看看落地的配置。
- 到达率单位时间内新提交任务的个数,用 λ 表示,可以理解为食堂每分钟进店的人数。
- 服务率单位时间内调度器能处理完的任务数,用 μ 表示,即窗口每分钟能打多少份饭。
- 系统利用率到达率与服务率的比值 ρ,表示系统有多忙。
- 平均等待时间任务在队列中等待的时间,与利用率成正比,与剩余服务能力成反比。
配置最佳实践
食堂经理把所有的规矩写成一本《食堂管理手册》:窗口怎么设、餐券怎么发、蒸锅怎么分、每桌限额多少。GPU 集群的调度配置也是一本“手册”,只是它写在不同系统的配置文件里。最主流的两个调度系统——Slurm 和 Kubernetes——各有各的写法,但思路相通。
Slurm 是传统 HPC 领域的事实标准。管理员通过 slurm.conf 定义多个 Partition(分区),每个分区相当于一个队列,可以设置 PriorityTier(优先级层级)、MaxTime(最长运行时间)、MaxNodes(最大节点数)等参数。作业提交时用 -p 指定分区,用 --priority 或 --qos 设置优先级。Slurm 还支持多因素优先级插件,把年龄(等待时间)、QOS、公平共享因子加权计算成最终优先级。
Kubernetes 则是云原生时代的选择。它通过 PriorityClass 对象定义优先级:创建一个名为 high-priority 的 PriorityClass,设置 value: 1000000,再把 Pod 关联到它,调度器就会优先调度该 Pod。kube-scheduler 支持抢占(Preemption),高优先级 Pod 无法调度时会驱逐低优先级 Pod。ResourceQuota 和 LimitRange 则负责配额管理。
实战中,组合配置才能发挥最大效果:用队列组织任务流,用权重控制比例,用优先级处理紧急任务,用配额设置上限。例如,一个 100 卡的集群可以这样规划:在线推理队列权重 5、配额 50 卡、优先级最高;模型训练队列权重 3、配额 35 卡;离线评测队列权重 1、配额 15 卡、优先级最低。最后,别忘了持续监控——每周看一次队列堆积量、平均等待时间、GPU 利用率,按实际情况调整权重和配额。
手册写好了,食堂才能高效运转。Slurm 和 K8s 只是不同的“手册格式”,背后都是同一套管理哲学:队列定秩序、优先级定先后、权重定比例、配额定边界、监控定调优。掌握了这套组合拳,你就能从容地经营一个服务数千人的“GPU 食堂”。
- 业务等级管理员为任务类别设定的基础优先级,如关键业务 100、普通任务 10。
- 等待时长任务入队后已经等待的时间,单位可以是分钟或小时。
- 补偿系数一个可调的超参数 α,决定等待时间对最终优先级的影响力度。
- 最终优先级业务等级加上等待补偿,作为调度器排序的最终依据。
AI 应用场景
大模型训练平台的团队级队列治理
阶段:算力资源调度与治理(MLOps)
解决的问题:多个算法团队共享 GPU 集群时,核心训练任务常被离线批处理任务堵住。传统做法是人工协调:谁急着用卡就找人改配置,效率低且容易出错。通过队列权重与优先级组合,能让紧急实验自动“插队”,低优任务只在空闲时运行。
具体案例:某公司 100 卡集群中,A 团队做在线推理(时延敏感),B 团队跑夜间训练(可等待)。管理员建了三个队列:高优在线(权重 5、配额 50 卡)、普通训练(权重 3、配额 35 卡)、离线批处理(权重 1、配额 15 卡),并给在线推理任务设置最高 PriorityClass。结果在线推理时延稳定在 50ms 内,训练任务也能在 2 小时内等到卡。
高校计算中心的 Slurm 多租户管控
阶段:HPC 集群运维与科研计算支持
解决的问题:全校各课题组共用一台 Slurm 集群时,热门的深度学习组总把 GPU 占满,冷门课题组的作业永远排不上。手动删任务、私下协调屡见不鲜。通过分区(Partition)加优先级层级(PriorityTier)加 QOS 配额,把资源分配规则制度化。
具体案例:某高校计算中心为“国家重点项目”分区设 PriorityTier=1000,为普通课程作业设 PriorityTier=100;同时配置 QOS 限制单任务最长运行 7 天、每账号最多同时运行 20 个任务。短小的作业可以“插队”运行,长任务通过抢占被暂停后恢复,学生的课程实验不再需要熬夜抢卡。
K8s 集群的 GPU 共享与抢占
阶段:云原生平台调度与资源治理
解决的问题:K8s 集群中多个业务方共享 GPU 节点,低优先级的批处理模型推理与高优先级的在线 API 服务互相争抢资源,导致核心服务响应变慢。传统做法是给每个业务单独建集群,成本翻倍。
具体案例:某 AI 平台在 K8s 上定义了三个 PriorityClass:critical(value=1000000)用于在线 API,normal(value=1000)用于模型训练,batch(value=100)用于数据预处理。当 GPU 不足时,batch Pod 会被 critical Pod 抢占驱逐;配合 ResourceQuota 限制每个命名空间最多 50 卡,杜绝了单业务“囤卡”现象。
Python 演示
#!/usr/bin/env python3# -*- coding: utf-8 -*-"""加权优先级调度模拟器: 演示GPU集群中队列权重与优先级抢占的基本逻辑"""import random class Task: """一个GPU作业任务, priority越小优先级越高""" def __init__(self, tid, priority): self.tid = tid self.priority = priority # 0 高, 1 中, 2 低 self.remaining = random.randint(3, 8) # 剩余执行秒数 def __repr__(self): return "Task({}, P{})".format(self.tid, self.priority) class WeightedScheduler: """按权重轮询 + 高优抢占 的简易调度器""" def __init__(self, weights, gpu_num=4): self.weights = weights # [3, 2, 1] 代表高:中:低 self.queues = [[], [], []] self.gpus = [None] * gpu_num self.clock = 0 self.cursor = 0 # 权重轮询游标 self.total_weight = sum(weights) self.finished = [] self.task_count = 0 def submit(self, priority): self.queues[priority].append(Task(self.task_count, priority)) self.task_count += 1 def _pick_queue(self): """按权重比例轮询, 返回当前可取的队列编号, 无任务则返回None""" for _ in range(self.total_weight): pos = self.cursor % self.total_weight acc = 0 for i, w in enumerate(self.weights): acc += w if pos < acc: self.cursor += 1 if self.queues[i]: return i break self.cursor += 1 return None def _preempt(self): """高优任务在GPU全满时抢占低优任务, 被抢占者回到队首""" for qi in range(len(self.queues)): if not self.queues[qi]: continue victim = -1 victim_prio = -1 for i, gpu in enumerate(self.gpus): if gpu is not None and gpu.priority > qi and gpu.priority > victim_prio: victim_prio = gpu.priority victim = i if victim >= 0: old = self.gpus[victim] old.remaining += 1 self.queues[old.priority].insert(0, old) self.gpus[victim] = self.queues[qi].pop(0) return True return False def step(self): self.clock += 1 r = random.random() if r < 0.35: self.submit(2) elif r < 0.70: self.submit(1) else: self.submit(0) for i in range(len(self.gpus)): if self.gpus[i] is not None: self.gpus[i].remaining -= 1 if self.gpus[i].remaining <= 0: self.finished.append(self.gpus[i]) self.gpus[i] = None if self.gpus[i] is None: qi = self._pick_queue() if qi is not None: self.gpus[i] = self.queues[qi].pop(0) if all(g is not None for g in self.gpus): self._preempt() def run(self, steps=200): for _ in range(steps): self.step() return len(self.finished) if __name__ == "__main__": sch = WeightedScheduler(weights=[3, 2, 1], gpu_num=4) done = sch.run(200) remain = sum(len(q) for q in sch.queues) per_prio = [0, 0, 0] for t in sch.finished: per_prio[t.priority] += 1 print("==== 加权优先级调度模拟结果 ====") print("提交任务总数:", sch.task_count) print("完成数量:", done, " 仍在排队:", remain) print("高/中/低优先级完成数:", per_prio)
class WeightedScheduler:定义一个调度器类,内部包含队列、GPU 槽位和轮询游标。self.weights = weights保存队列权重配置,如高:中:低 = 3:2:1,权重大的队列调度机会多。self.queues[priority].append(...)新任务提交时进入对应优先级的队列,相当于食堂员工站到对应窗口的队伍末尾。pos = self.cursor % self.total_weight用游标取模实现权重轮询,游标每走一步选一个队列。if pos < acc: ... return i判断游标落在哪个权重区间,落在哪个区间就选哪个队列出队。if gpu.remaining <= 0: self.finished.append(gpu)任务执行完毕,释放这个 GPU 槽位并记入完成列表。old.remaining += 1被抢占的任务重新入队时增加 1 秒惩罚开销,模拟“被赶下 GPU 后的冷启动损耗”。if all(g is not None for g in self.gpus): self._preempt()只有全部 GPU 都忙时才触发抢占,避免不必要的任务迁移。
常见误区
误区把任务的优先级设到最高,提交后就能马上拿到 GPU 开始跑,不用排队。
正解优先级只决定“排队顺序”,不改变“资源是否可用”这一前提。如果集群的 GPU 全部被其他高优任务占满,且没有可抢占的低优任务,最高优先级的任务也只能等着。就像食堂的 VIP 券只能让你排到最前面,但如果打饭窗口全都忙不过来,VIP 也得等出餐。
为何常见:很多运维文档强调“高优先级任务优先调度”,让初学者误以为优先级高等于“瞬间执行”,忽略了资源容量和排队前提。
误区给 A 队列设了权重 5,那 A 队列就永远独占 5 份资源,其他队列碰都不能碰,即使 A 队列根本没用满。
正解权重描述的是“竞争状态下的分配比例”,不是“预留的专属资源”。当高权重队列空闲时,它的份额会自动让给其他有需求的队列使用,以提高集群利用率。类比食堂的蒸锅:套餐窗口有 3 口锅,但面食窗口排长队时,套餐窗口空着的锅可以借来蒸馒头。
为何常见:把“权重”和“配额”混为一谈。权重强调弹性共享、按比例分配;配额强调绝对上限。两者是不同维度的机制。
误区给每个团队都设置接近集群总量的配额上限,这样自己想用多少都有保障。
正解配额上限设得过大等于没有配额。如果所有租户都设成集群总量,出现资源竞争时调度器无法保证任何一家的资源底线,排队时间不可预期。合理的做法是:配额上限覆盖团队 90% 场景的峰值需求,再留一个共享池应对突发流量。
为何常见:看到“配额”二字就联想到“帮我预留的资源”,忽略了配额只是“最多能用多少”的限制,并不具备预留语义。
误区集群搭建时把队列、权重、配额一次性配好,之后就再也不用管了,任务排队慢就是集群不行。
正解业务负载是动态变化的:新团队加入、旧任务变多、模型规模翻倍、节假日用量骤降。管理员需要定期观察各队列的堆积量、平均等待时间、GPU 利用率,动态调整权重和配额。食堂经理也不可能只开学第一天定规矩就再也不看窗口排队情况。
为何常见:配置文件写好后静态存储,看起来像“基础设施”,让人误以为调度策略是一次性工程,忽略了资源治理是持续运营的过程。
面试题
Q1. GPU集群中引入“队列”的核心目的是什么?
- A.让所有作业随机获得资源
- B.有序管理等待中的作业← 正确答案
- C.提高每个任务的运行速度
- D.减少服务器上的GPU数量
答案:B。队列把等待资源的作业排成有序序列,按规则依次调度,就像食堂窗口前的队伍。随机获取会让调度混乱,队列本身不加速任务运行,也不改变 GPU 数量。
Q2. 队列默认的调度顺序通常是哪种?
- A.后进先出按栈的顺序
- B.随机选取任一作业运行
- C.先来后到依次执行← 正确答案
- D.按作业大小倒序排列
答案:C。默认先进先出(FIFO),先提交的作业先获得资源。这保证排队秩序可预测,用户能估算等待时间。后进先出、随机、倒序都不是默认规则。
Q3. 关于任务的优先级数值,下列哪项说法正确?
- A.数值越大优先级越高
- B.数值越小优先级越高← 正确答案
- C.数值大小与优先级无关
- D.所有任务的优先级相同
答案:B。在 Slurm 和 K8s 等主流调度器中,优先级数值越小代表级别越高,越先被调度。好比餐券等级 1 级永远排在 3 级前面。
Q4. 权重为3:2:1的三个队列,高优队列理论应得多少资源?
- A.三分之一左右的资源
- B.二分之一左右的资源← 正确答案
- C.六分之一左右的资源
- D.百分百的集群资源
答案:B。总权重是 3+2+1=6,高优队列占 3/6=1/2,即一半资源。权重决定竞争时的分配比例,而不是固定数量。
Q5. 资源配额 Q_min 的主要作用是什么?
- A.限制集群最大资源总量
- B.保证租户最低资源底线← 正确答案
- C.提高任务单个执行速度
- D.禁止租户使用共享资源
答案:B。Q_min 是最小保证配额,调度器承诺优先为该租户补足这部分资源,防止某团队永远抢不到资源。它与集群总量无关,也不影响单任务速度。
Q6. 加权公平调度中“防饿死”机制解决的是什么问题?
- A.高优任务抢占低优任务
- B.低权重队列长期拿不到资源← 正确答案
- C.任务执行时间无限延长
- D.队列中任务数量无限增长
答案:B。防饿死保证即使权重极低的队列也能获得最少一份资源,不让小团队永远排不上。类比食堂保证每家公司至少能订到一份午饭。
Q7. 排队论中当系统利用率趋向于1时,平均等待时间如何变化?
- A.线性缓慢地增加
- B.逐渐降低趋于零
- C.急剧快速地增加← 正确答案
- D.保持恒定不再变化
答案:C。由 W_q = ρ/(μ-λ) 可知,当利用率 ρ 趋近 1 时,μ-λ 趋近 0,等待时间趋向无穷大。因此几乎满载的集群会出现排队时间急剧恶化。
Q8. 哪些方式可以影响一个任务的调度优先级?
- A.用户提交时显式指定← 正确答案
- B.等待时间自动增长← 正确答案
- C.修改服务器网卡型号
- D.业务紧急度高级策略← 正确答案
答案:ABD。用户可显式设优先级;多因素优先级插件会让等待时间参与计算;管理员也能为关键业务设置更高基础优先级。网卡型号与 CPU 调度优先级无关。
Q9. 关于高优先级任务的抢占机制,正确的有哪些?
- A.GPU全忙时高优可抢占低优← 正确答案
- B.被抢占的任务会回到队列中← 正确答案
- C.抢占过程完全没有任何开销
- D.抢占通常伴随着迁移开销← 正确答案
答案:ABD。抢占发生在资源全忙且高优任务到来时,被抢占任务回到队列重新排队。抢占涉及保存/恢复状态、重新调度等开销,并非零成本。
Q10. Slurm 与 Kubernetes 中配置优先级常用的手段是哪些?
- A.Slurm 中设置分区优先级权重← 正确答案
- B.K8s 中创建 PriorityClass 对象← 正确答案
- C.直接修改内核的任务调度器
- D.等待时间自然增长来调节← 正确答案
答案:ABD。Slurm 用 PriorityTier/多因素优先级,K8s 用 PriorityClass 的 value 值,等待时长作为年龄因子参与计算。修改内核调度器属于系统底层操作,不是应用层常规配置手段。