一、调度策略:GPU集群的交通指挥官
调度策略这东西,说白了就是决定「下一个轮到谁上GPU跑」。
我刚开始接触集群调度时,觉得不就是排队嘛,谁先来谁先跑。后来被生产环境狠狠教育了一顿——你想想看,一个32卡的任务堵着,后面8个4卡的小任务干瞪眼,这合理吗?
所以今天咱们聊聊四种最常见的调度策略。每种我都踩过坑,也总结了一些实战经验。
1. FIFO调度:简单但粗暴
FIFO,全称First In First Out,先进先出。这是最朴素的调度方式。
核心逻辑:任务按提交时间排成一个队列,谁先来谁先获得资源。后面的任务只能等前面的跑完。
优点:
- 实现简单,几乎零开销
- 公平性直观,没人插队
- 适合短任务、低负载场景
缺点:
- 容易产生「队头阻塞」——一个大任务堵住后面所有小任务
- 资源利用率低,GPU可能空闲等待
- 不支持优先级,紧急任务也得排队
我在项目中遇到过这样一个场景:某团队提交了一个需要跑48小时的训练任务,结果后面20多个推理任务全部卡死。用户投诉电话打爆了。嗯,这就是FIFO的典型悲剧。
我的建议:FIFO只适合开发测试环境,或者任务类型单一、执行时间相近的场景。生产环境慎用。
2. 公平调度:雨露均沾
公平调度(Fair Scheduling)的思路是——每个用户或每个队列,都能获得大致相等的资源份额。
它的核心机制是资源池化和动态调整。比如集群有100张GPU,A用户提交了10个任务,B用户提交了2个任务,公平调度会让A和B各拿50张卡,而不是让A独占。
具体实现上,公平调度会计算每个队列的「资源权重」,然后按权重分配。如果某个队列暂时没任务,它的份额可以借给其他队列用——这叫「资源借贷」。等那个队列有任务了,再还回来。
公平调度的关键参数:
| 参数 | 说明 | 我的经验值 |
|---|---|---|
| minShare | 最小保证资源量 | 设为队列日常负载的60% |
| weight | 队列权重 | 核心业务权重设高一些 |
| maxShare | 最大资源上限 | 防止某个队列吃光所有资源 |
我曾经踩过一个坑:公平调度默认会抢占正在运行的任务来重新分配资源。有一次,一个训练任务跑了30小时,快结束时被抢占,结果前功尽弃。后来我加上了preemptionTimeout参数,让任务运行超过一定时间后不再被抢占。
注意:公平调度不是绝对公平。它追求的是「资源份额的公平」,而不是「任务数量的公平」。大任务和小任务在资源分配上是有区别的。
3. 容量调度:分田到户
容量调度(Capacity Scheduling)有点像「分田到户」。每个队列有固定的资源上限,互不干扰。
它的设计思路是:把集群资源划分成多个「容量池」,每个队列只能使用自己池子里的资源。即使其他队列空闲,也不能越界使用。
举个例子:集群有100张GPU,分成三个队列:
- AI训练队列:50张
- 推理服务队列:30张
- 开发测试队列:20张
推理服务队列即使空闲,AI训练队列也不能占用它的30张卡。这样做的好处是——资源隔离,互不影响。
容量调度 vs 公平调度:
| 特性 | 容量调度 | 公平调度 |
|---|---|---|
| 资源隔离 | 强隔离,互不借用 | 弱隔离,可借用 |
| 资源利用率 | 可能较低(空闲资源浪费) | 较高(动态借用) |
| 适用场景 | 多租户、SLA严格的场景 | 内部团队、资源共享场景 |
我个人习惯在容量调度中设置一个「弹性容量」参数。比如某个队列的容量是50张,但允许它临时借用其他队列的空闲资源,最多到70张。这样既保证了隔离,又提高了利用率。
4. 优先级调度:VIP通道
优先级调度,顾名思义——给任务打标签,高优先级的先跑。
实现方式通常有两种:
- 静态优先级:任务提交时指定优先级,调度器按优先级排序
- 动态优先级:根据任务等待时间、资源需求等因素动态调整优先级
我在生产环境中用的是「优先级+时间衰减」的混合策略。具体来说:
- 任务初始优先级由用户指定(1-10级)
- 每等待1小时,优先级自动+0.5
- 优先级相同的任务,按FIFO顺序执行
这样做的好处是:高优先级任务能快速获得资源,但低优先级任务也不会被饿死——等久了,它的优先级自然就上来了。
避坑指南:我曾经遇到过一个问题——某个用户把所有任务都标为最高优先级。结果整个调度系统失效,所有任务都变成了VIP。后来我加了限制:每个用户最多只能有20%的任务设置为最高优先级。
5. 四种策略的对比与选择
说了这么多,到底该用哪种?我整理了一张对比表:
| 策略 | 核心思想 | 资源利用率 | 公平性 | 复杂度 | 推荐场景 |
|---|---|---|---|---|---|
| FIFO | 先来先服务 | 低 | 低 | 极低 | 开发测试 |
| 公平调度 | 按权重分配 | 高 | 高 | 中 | 内部共享集群 |
| 容量调度 | 固定资源池 | 中 | 中 | 中 | 多租户生产环境 |
| 优先级调度 | 按标签排序 | 高 | 低 | 低 | 紧急任务优先 |
实际生产中,我很少只用一种策略。通常是「容量调度+优先级调度」组合使用——先按容量划分资源池,再在池内按优先级调度。这样既保证了隔离,又保证了灵活性。
6. 一张图看懂调度策略
下面这张SVG图,展示了四种调度策略的核心逻辑:
这张图把四种策略的核心逻辑画出来了。你看,FIFO就是一条直线排队,公平调度是动态分配,容量调度是固定划分,优先级调度是VIP插队。
实际选型时,我建议你先问自己三个问题:
- 你的集群是单租户还是多租户?
- 任务类型是否多样?执行时间差异大不大?
- 有没有紧急任务需要插队?
想清楚这些,调度策略的选择就清晰了。
最后说一句:调度策略不是一成不变的。我见过不少团队,一开始用FIFO,后来换成公平调度,再后来改成容量调度+优先级组合。随着业务发展,调度策略也要迭代升级。
好了,这四种调度策略就聊到这里。每种都有它的用武之地,关键是要理解它们的本质——资源分配的艺术。
想要更多资料,联系可可