当前位置:首页|资讯

Volcano-Gang调度实现源码分析

作者:BeijingToTokyo发布时间:2024-10-01

1  引言

Gang调度策略是volcano-scheduler的核心调度算法,它满足了调度过程中的“All or nothing”的调度需求,避免Pod的随意调度导致任务之间资源死锁的痛点问题。变向的提高了集群的资源利用率。

本文主要通过源码分析gang调度实现原理,也对前文进行一些补充。 

阅读本文前可以先阅读前文


2  前置知识

2.1 理解调度器源码中的 Job 和 Task  

在看具体代码前,需要了解:

  • 在volcano-scheduler的源码里 Task 对应 Pod,是对一个待调度的 k8s Pod 资源的一个封装,Tasks 的也就是一组 Pod 的集合。

  • 在volcano-scheduler的源码里 JobInfo 类型的 job 变量,对应着 PodGroup,代表着一个任务中的全体Pod, JobInfo结构体属性里包含 tasks 字段。 JobInfo 结构体属性里包含 PodGroup 字段。

JobInfo结构体


JobInfo中 `minTaskNumber` 和 `minAvailable` 是两个与任务调度策略相关的字段。较易混淆,笔者在这里分别解释:

  • minTaskNumber 在 Volcano调度器中的使用

    确保作业达到最小并行度:它保证了作业开始时会以一个指定的最小并行度(即最少同时运行N个Pod,任务才能正常运行)。如果当前集群中没有足够的资源来启动minTaskNumbe 个数的Pod,作业将不会被调度。这保证了作业被调度后,至少可以正常进行任务计算的。

  • minAvailable 这个参数并不是Volcano调度器特有的配置项,是Kubernetes原生的能力

    Kubernetes 原生的Deployment和StatefulSets等  通常用  minAvailable字段 来定义在更新或伸缩过程中至少要保持的副本(Pod)数量。这有助于确保服务持续可用,并减少更新操作对用户的影响。minAvailable 重点在于保证服务级别的可用性而不是单个任务或作业的并发执行。

2.2 理解调度器源码中的 Session 和 Statement

Statement 是一次调度的载体,每一次调度都会重新生成一个Statement实例,其结构体由Session和待操作列表组成,当前集群的整体资源视图和调度器的配置项保存在Session中。

Sataement实现了 Discard、Commit 等方法,负责最后执行 取消本次调度 或 提交本次调度结果。

Statement和Session


2.3 Volcano-Scheduler 的启动流程

调度器启动流程

下面官方流程图中的 OpenSession 和 CloseSession 就在RunOnce函数中。

官方流程图


2.4 Action 和 Plugin

从官方流程图中可见 enqueue、allocate、preempt、reclaim、backfill。这些调度中历经的步骤叫做Action,而 Plugin 实现了各个步骤中具体的调度策略(policy)。

Action 和 Plugin 在都是一种golang接口,可以从代码中查看接口的实现。

Action 和 Plugin 接口

3  源码分析

3.1 源码调用关系图

我们由pc.runOnce开始阅读源码,处理流程如下图:


上图说明:


3.2 Gang调度最核心的函数JobReady详解

3.2.1 判断JobReady

在判断JobReady时会先统计Job中已Ready的Pod数,使用ReadyTaskNum函数

ReadyTaskNum函数

ReadyTaskNum函数中会把Pending状态的BestEffort task也计算为Ready,这是因为BestEffort task会在后面的backfill Action调度成功,所以计数时可以把其看作是调度完成的。

用ReadyTaskNum函数返回的值进行JobReady判断


3.2.2 回填剩余Job

如果一个Job已经满足Ready条件,但此时for遍历并未完结,Job中还有未遍历处理到的task,会先把包含未处理task的Job信息【本次Session处理,未pop出的剩余部分】进行回填,将其Push回Jobs【job的优先级队列】,待之后的Session进行处理。

将剩余的Job Push回Job的优先级队列中


3.2.3 预选函数逻辑

预选函数PredicateFn

这里的逻辑是接收一个 task 和 node 作为参数,然后判断这个 node 上能否跑起来这个 task。返回值 Status 类型是一个结构体,定义如下:

Status结构体

Code 的可选值有6个:Success、Error、Unschedulable、UnschedulableAndUnresolvable、Wait、Skip.这里主要需要理解三个状态:

  • Success:可调度

  • Unschedulable:不可调度,但是驱逐后可能可调度

  • UnschedulableAndUnresolvable:不可调度且驱逐也不可调度

后续的调度判断中会使用这个Code的值

判断预处理函数的Code值



Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1