第 8 篇|Volcano 资源竞争:队列份额与作业调度

第 8 篇|Volcano 资源竞争:队列份额与作业调度

💡 原文中文,约7000字,阅读约需17分钟。
📝

内容提要

本文解析 Volcano 多作业资源共享与竞争机制:Queue 通过 proportion 插件按权重、需求、上限和保障量计算 deserved 份额;DRF 以主导资源份额排序作业;preempt 处理队列内抢占,reclaim 处理跨队列回收,均需检查优先级、可抢占性、Gang 与节点约束。驱逐后资源不会立即可用,Ray 任务可能无法无损恢复。

🔎

延伸解读

资源份额计算与实时使用率的区别

Volcano 的 proportion 插件根据权重、需求和上限计算队列的 deserved 份额,但 allocated 是按 Pod 资源请求记账的,不是实时 CPU 使用率。因此,业务进程空闲时,只要 Pod 仍占用资源请求,调度器就认为队列还占着资源。排查时不要用实时利用率替代资源请求账目,否则会误判队列的资源占用情况。

权重比例不是固定占用比例

权重 1:2 只影响份额计算,实际分配还受需求、上限和保障量裁剪。例如总资源 12 核时,两队列权重 1:2 可能各得 4 核和 8 核;若第一队列只需 2 核,则变为 2 核和 10 核;若第二队列上限为 7 核,则变为 2 核和 7 核,剩余 3 核不计入份额。deserved 变化不会立即改变运行中的 Pod,需等待资源释放或回收。

队列排序与可分配性检查是两回事

proportion 注册的 Queue 排序函数先比较 Queue.spec.priority,再比较资源份额使用程度,使用程度低的队列排在前面。但从优先队列取出 Queue 后,还要执行可分配性检查,确认分配候选 Pod 后是否超过该队列本轮的 deserved。排序决定先检查谁,可分配性决定能否继续拿资源,节点过滤还可能失败。

preempt 与 reclaim 的竞争范围不同

传统 preempt 处理同一 Queue 内作业之间或同作业内成员之间的竞争,检查优先级、可抢占性、Gang 和节点条件。传统 reclaim 处理跨 Queue 的资源回收,检查来源队列的 reclaimable 设置和资源份额。两者都使用 Statement 推演,提交驱逐后资源不会立即可用,需等待受害 Pod 退出。对 Ray 应用,被驱逐的 worker 上的任务可能无法无损恢复。

Q&A

Volcano 中 Queue 的 deserved 份额是如何计算出来的?

以 proportion 插件为例,它根据 Queue 的 weight、需求(request)、上限(capability)和保障量(guarantee)计算 deserved。具体步骤:将剩余资源按权重比例加入各队列的 deserved,然后用 realCapability 和 request 进行裁剪,最后取 guarantee 作为下限。

Volcano 的 DRF 插件是如何比较不同作业的资源占用的?

DRF(Dominant Resource Fairness)计算每个作业在各类资源上的占用比例,取最大值作为该作业的主导资源份额。比较时,主导份额较小的作业排在前面。例如,一个作业占用 50% CPU 和 25% GPU,主导份额为 50%;另一个作业占用 12.5% CPU 和 50% GPU,主导份额也为 50%,两者相等。

Volcano 中 preempt 和 reclaim 有什么区别?

preempt 处理同一 Queue 内不同作业之间或同一作业内成员之间的资源竞争,检查优先级、可抢占性、Gang 和节点约束等。reclaim 处理跨 Queue 的资源回收,从其他队列中寻找允许回收的运行中成员,检查来源队列的 reclaimable 设置、资源份额等。两者都需检查优先级、可抢占性、Gang 和节点条件。

为什么 Volcano 中队列有资源份额,作业却仍然排队?

可能原因包括:未启用驱逐 Action,只能等待资源自然释放;作业未通过 enqueue 准入;Queue 未 Open 或 PodGroup 队列引用错误;资源碎片、GPU 型号、节点亲和性、污点等导致 Pod 无法放置;Gang 最低要求未满足;已触发驱逐但受害 Pod 尚未退出或等待成员未完成绑定。

Volcano 驱逐 Pod 后,资源会立即可用吗?

不会。驱逐提交后,需要等待受害 Pod 真正退出,资源才能成为可用。Pod 终止、缓存观察到变化、等待成员重新分配和绑定都有时间窗口。对于 Ray 应用,被驱逐的 worker 上可能有用户任务、actor 或内存对象,后续 Pod 补回不代表计算无损恢复,需依赖 Ray 的重试、检查点等机制。

Volcano 中 Queue 的 priority 和作业的 priority 有什么不同?

Queue.spec.priority 参与队列排序,决定先检查哪个队列的资源可分配性。PodGroup 引用的 PriorityClass 参与作业优先级排序,影响 JobOrder 回调中的比较。成员 Pod 也有自己的优先级字段。调试时需确认当前比较的是哪一层对象。

🏷️

标签

➡️

继续阅读