Volcano 作业资源预留设计原理解读

简介

Volcano 是一个基于 Kubernetes 的云原生批量计算平台,也是 CNCF 的首个批量计算项目。Volcano 主要用于 AI、大数据、基因、渲染等诸多高性能计算场景,对主流通用计算框架均有很好的支持。它提供高性能计算任务调度,异构设备管理,任务运行时管理等能力。本篇文章将深度剖析 Volcano 重要特性之——资源预留。

场景分析

在实际应用中,常见以下两种场景:

  • 在集群资源不足的情况下,假设处于待调度状态的作业 A 和 B,A 资源申请量小于 B 或 A 优先级高于 B。基于默认调度策略,A 将优先于 B 进行调度。在最坏的情况下,若后续持续有高优先级或申请资源量较少的作业加入待调度队列,B 将长时间处于饥饿状态并永远等待下去。

  • 在集群资源不足的情况下,假设存在待调度作业 A 和 B。A 优先级低于 B 但资源申请量小于 B。在基于集群吞吐量和资源利用率为核心的调度策略下,A 将优先被调度。在最坏的情况下,B 将持续饥饿下去。

以上两种场景出现的根因是缺少一种公平调度机制:保证长期处于饥饿状态的作业在达到某个临界条件后被优先调度。造成作业持久饥饿的原因很多,包括资源申请量长时间无法满足、优先级持续过低、抢占发生频率过高、亲和性无法满足(v1.1.0 暂不支持此场景)等,以资源申请量无法满足最为常见。

特性设计

为了保证长期处于阻塞状态的作业能够拥有公平的调度机会,需要解决两个主要问题:

  • 如何识别目标作业?

  • 如何为目标作业预留资源?

目标作业识别

作业条件

作业条件的选定可以基于等待时间、资源申请量等单个维度或多个维度的组合。综合考虑,v1.1.0 实现版本选择优先级最高且等待时间最长的作业作为目标作业。这样不仅可以保证紧急任务优先被调度,等待时间长度的考虑默认筛选出了资源需求较多的作业。

作业数量

客观来说,满足条件的作业通常不止一个,可以为目标作业组或单个目标作业预留资源。考虑到资源预留必然引起调度器性能在吞吐量和延时等方面的影响,v1.1.0 采用了单个目标作业的方式。

识别方式

识别方式有两种:自定义配置和自动识别。v1.1.0 暂时仅支持自动识别方式,即调度器在每个调度周期自动识别符合条件和数量的目标作业,并为其预留资源。后续版本将考虑在全局和 Queue 粒度支持自定义配置。

资源预留算法

资源预留算法是整个特性的核心。v1.1.0 采用节点组锁定的方式为目标作业预留资源,即选定一组符合某些约束条件的节点纳入节点组,节点组内的节点从纳入时刻起不再接受新作业投递,节点规格总和满足目标作业要求。需要强调的是,目标作业将可以在整个集群中进行调度,非目标作业仅可使用节点组外的节点进行调度

节点选取

在特性设计阶段,社区考虑过以下节点选取算法:规格优先、空闲优先。

规格优先是指集群中所有节点按照主要规格(目标作业申请资源规格)进行降序排序,选取前 N 个节点纳入节点组,这 N 个节点的资源总量满足申请量。这种方式的优点是实现简单、锁定节点数量最小化、对目标作业的调度友好(这种方式锁定的资源总量往往比申请总量大一些,且作业中各 Pod 容易聚集调度在锁定节点,有利于 Pod 间通信等);缺点是锁定资源总量大概率不是最优解、综合调度性能损失(吞吐量、调度时长)、易产生大资源碎片。v1.1.0 的实现采用的是该算法。

空闲优先是指集群中所有节点按照主要资源类型(目标作业申请资源类型)的空闲资源量进行降序排序,选取前 N 个节点纳入节点组,这 N 个节点的资源总量满足申请量。这种方式的优点是较大概率最快腾出满足要求的资源总量;缺点是集群空闲资源分布的强动态性导致节点组不是最优解,所求解稳定性差。

节点数量

为了尽可能减少锁定操作对调度器综合性能的影响,在满足预留资源申请量的前提下,无论采用哪种节点选取算法,都应保证所选节点数最少。

锁定方式

锁定方式包括两个核心考量点:并行锁定数量、锁定节点已有负载处理手段。

并行锁定数量有三个选择:单节点锁定、多节点锁定、集群锁定。单节点锁定是指每个调度周期内基于当前集群资源分布选定一个符合要求的节点纳入节点组。这种方式可以尽量减少资源分布波动对所求解的稳定性的影响,缺点是要经过较多的调度周期才能完成锁定过程。v1.1.0 的实现选择的是这种方式。

以此类推,多节点锁定是指每个调度周期内选定 X(X>1)个满足条件的节点进行锁定。这种方式能一定程度上弥补单节点锁定引入的锁定时长过长问题,缺点是 X 不易找到最优值,实现复杂度高。

集群锁定是指一次性锁定集群所有节点,直至目标作业完成调度。这种粗暴的方式实现最为简单,目标作业等待时间最短,非常适合超大目标作业的资源预留。

锁定节点已有负载的处理手段有两种:抢占式预留、非抢占式预留。顾名思义,抢占式预留将会强制驱逐锁定节点上的已有负载。这种方式可以保证最快腾出所需的资源申请量,但会对已有业务造成重大影响,因此仅适用于紧急任务的资源预留。非抢占式预留则在节点锁定后不做任何处理,等待运行在其上的负载自行结束。v1.1.0 采用的是非抢占式预留。

最佳实践

基于 v1.1.0 的实现,社区当前仅支持目标作业的自动化识别与资源预留。为此,新引入了 2 个 action 和 1 个 plugin。elect action 用于选取目标作业;reserve action 用于执行资源预留动作;reservation plugin 中实现了具体的目标选取和资源预留逻辑。

若要开启资源预留特性,将以上 action 和 plugin 配置到 volcano 的配置文件中即可。

下面是推荐配置样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
actions: "enqueue, elect, allocate, backfill, reserve"
tiers:
- plugins:
- name: priority
- name: gang
- name: conformance
- name: reservation
- plugins:
- name: drf
- name: predicates
- name: proportion
- name: nodeorder
- name: binpack

自行配置时,请注意以下事项:

  • elect action 必须配置在 enqueue action 和 allocate action 之间

  • reserve action 必须配置在 allocate action 之后


结束福利

开源实战利用 k8s 作微服务的架构设计代码:

https://gitee.com/damon_one/spring-cloud-k8s
https://gitee.com/damon_one/spring-cloud-oauth2

欢迎大家 star,多多指教。


关于作者

  笔名:Damon,技术爱好者,长期从事 Java 开发、Spring Cloud 的微服务架构设计,以及结合 Docker、K8s 做微服务容器化,自动化部署等一站式项目部署、落地。目前主要从事基于 K8s 云原生架构研发的工作。Golang 语言开发,长期研究边缘计算框架 KubeEdge、调度框架 Volcano 等。公众号 程序猿Damon 发起人。个人微信 MrNull008,个人网站:Damon | Micro-Service | Containerization | DevOps,欢迎來撩。


欢迎关注:InfoQ

欢迎关注:腾讯自媒体专栏


欢迎关注

公号:程序猿Damon

公号:damon8

公号:天山六路折梅手


打赏

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2020-2021 码疯窝在香嗝喱辣
  • Powered By Hexo | Title - Nothing
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信