队列#
队列是AIP作业的载体。用户提交作业到队列中,由AIP的调度器根据作业资源需求、集群中可用的资源、 和 cb.yaml 里配置的调度策略调度和分发队列里的作业到合适的计算主机上。
AIP里的队列由调度器管理。缺省队列与集群挂钩,这样队列不会受某个主机的状态而影响作业提交。
队列配置的例子#
AIP中可以根据不同的需求配置多个队列,队列配置里和很多参数。常用的参数有:用户(users)、 主机(hosts)、和缺省资源需求(resspec)。
一般不同的应用需要不同的资源,如一些应用需要大内存,一些需要GPU等。一般的队列设置一应用类别 来设置不同的队列。每一类应用,即每个队列,根据其资源需求设置队列所用的主机。同时可以根据用户 使用应用的权限配置可用该队列的用户。
例子1:按应用分队列#
计算中心给3类应用:
MPI类的HPC应用,如计算流体力学OpenForm 这类应用需要使用大量的CPU,而对内存的需求不太大。
图形设计仿真应用,如FreeCAD、用户图形桌面 这类应用需要较大的内存和用于图形加速的GPU。
AI模型训练和一些可以用GPU加速的应用 这类应用需要已使用GPU为主。
cb.yaml(企业版)配置:
# 配置3个主机组,每一个针对一种应用选用转为这类应用准备的服务器
# 如果要调整主机的用途,只要修改这部分配置即可
hostgroups:
- name: compute # 运行MPI作业的CPUCPU计算类主机
members: c[01-10] # 10 台主机,名为c01, c02, ... c10
- name: gcompute # 运行AI所用的GPU主机
members: g[01-04] # 4 台GPU主机:g01, g02, g03, g04
- name: desktop # 用户交互任务的主机
members: d01 d02 d03 # 3 台主机
# 配置使用不同应用的用户组
usergroups:
- name: cae # 使用LDAP中的用户组cae
members: "@system" # @system表示组员由操作系统决定,AIP
# 每小时会与系统同步一次组员信息,如果
# LDAP里用户组成员修改了,1小时内会
# 自动同步到AIP中
usermaxslots: 64 # 每个用户最多用64个作业槽(CPU核),
# 防止一个用户把这个作业槽都占了
- name: ml # 可以跑AI训练的用户
members: user01 user02 user03
administrator: user01 # 这个用户组有一个管理员,可以控制
# 组内其他用户的作业
# 配置队列
queues:
- name: gui # 所有用户都可以使用
description: 运行交互式桌面或图形应用
priority: 3 # 队列优先级,由于队列使用专属的主机
# 优先级数字不重要
hosts: desktop # 使用desktop主机组的主机
usermaxslots: 2 # 每个用户最多用2个作业槽
memlimit: percore # 按照CPU核数平均分配内存,并限制内存
# 使用,超过内存限制的作业会被调度器
# 杀掉
- name: comp
description: 运行并行作业的CPU队列
priority: 3
hosts: compute
users: cae
fairshare: "[default, 1]" # 公平分享策略,每个用户等同的份额
- name: gpu
description: GPU计算为主的应用
priority: 3
hosts: gcompute # 使用GPU主机组
users: ml # 只限ml组的用户使用
resspec: rusage[gpu=0.25] # 按作业槽平均分配GPU,这里每台主机
# 上有8个GPU, 32个CPU核(作业槽),每个
# 作业槽预留1/4个GPU
# 调度器通用配置
general:
default_queue: gui # 如果提交作业时不指定队列,用缺省的队列gui
cgroup: acct gpu # 使用Linux cgroup控制作业GPU的使用
mailprog: ":" # 作业结束后不自动送邮件
# 集群配置
cluster:
name: aip
administrators:
- cadmin
hosts:
- name: mgt[01-02] # 两台管理节点,不运行作业
maxslots: 0
- name: c[01-10]
- name: g[01-04]
- name: d[01-03]
- name: default
maxslots: cpu
enterprise: yes
例子2:优先级抢占#
EDA公司的集群提供VNC桌面和EDA计算资源。有一个小组的工程师不是需要跑一些高优先级的作业。 高优先级作业需要抢占普通EDA计算作业所用的资源。
cb.yaml(企业版)配置:
# 配置两个主机组
hostgroups:
- name: desktop # 用于VNC桌面的主机组
members: d01 d02 d03
- name: compute # EDA计算主机
members: all ~desktop # 集群中除了VNC桌面主机外的其他主机
# 配置3个队列
queues:
- name: medium
description: 通用计算队列
priority: 3
fairshare: "[default,1]" # 每个用户有相同的份额,防止单一用户占据整个集群
hosts: compute # EDA计算主机组
rerunonhostfail: yes # 如果某台主机出故障,自动重调度主机上跑的作业
- name: vnc
description: 桌面队列
priority: 3
hosts: desktop
usermaxslots: 2 # 每个用最多两个作业槽
- name: high
description: 高优先级队列,可以抢占普通作业所占的资源
priority: 10 # 优先级只要高于medium队列即可
preemption: medium # 如果集群里没有资源,杀掉并让medium队列中的
# 一部分作业,并让被杀掉的作业自动重排队
users: user03 user04 # 只用用户user03和user04可以使用这个队列
# 调度器通用配置
general:
default_queue: medium # 一般作业都缺省提交到medium队列
# 集群配置
cluster:
name: aip
administrators:
- cadmin
hosts:
- name: mgt01
maxslots: 0
- name: c[01-10] # 由于集群较小,c01和c02作为管理节点
# 的备选主机(缺省hosts列表中前3台为master主备机)
- name: d[01-03]
- name: default
define_ncpus: threads
maxslots: cpu
enterprise: yes
例子3:主机拥有、共享、和抢占#
两个小组(rd1和rd2)把自己拥有的服务器合并成一个集群,但每个小组在自己拥有的主机上都有优先级,并可以抢占 其他用户在上面跑的作业。
公司另外有一批公共所有的主机也加到了集群中,这部分主机所有用户共享。

如上图所示,rd1和rd2都有自己拥有的资源池(c01-c03和c04-c06),中间(c07-c10)有共享的资源池。
这3个资源池共属一个集群。
每个组里的资源池中若自己组的人不用,可共享给其他组的人用。
自己组里的任务在自己的资源池中可以抢占其他组里任务的资源,抢占只限于自己的组的资源池中。
cb.yaml(企业版)配置:
# 用户组
usergroups:
- name: rd1
members: "@system" # LDAP中rd1组
- name: rd1
members: "@system" # LDAP中rd2组
# 配置3个队列
queues:
- name: medium
description: 普通队列,队列可以使用集群的所有主机
priority: 3
- name: qrd1
description: rd1用的队列
priority: 10
hosts: c[01-03]+ others # 优先使用自己拥有的主机
users: rd1 # 只有rd1组可以用这个队列
ownership_hosts: c[01-03] # 拥有主机c01 c02 c03
preemption: medium qrd2 # 可以在拥有的机器上抢占其他队列中的作业
- name: qrd2
description: rd2用的队列
priority: 10
hosts: c[04-06]+ others # 优先使用自己拥有的主机
users: rd2 # 只有rd2组可以用这个队列
ownership_hosts: c[04-06] # 拥有主机c04 c05 c06
preemption: medium qrd1 # 可以在拥有的机器上抢占其他队列中的作业
# 调度器通用配置
general:
default_queue: qrd1 qrd2 medium # 用户提交作业而不指明队列时,AIP按这里定义的
# 的顺序查找第一个用户可以使用的队列。
mailprog: ":" # 作业结束后不自动送邮件
user_view_alljobs: y # 允许普通用户查看所有用户的作业信息
# 集群配置
cluster:
name: aip
administrators:
- cadmin
hosts:
- name: mgt[01-02] # 两台管理节点,不运行作业
maxslots: 0
- name: c[01-10]
- name: default
maxslots: cpu
enterprise: yes
缺省抢占的动作为requeue,即杀掉作业然后放回对接中重新调度。若抢占为暂停进程, 在general里增加preemption_suspend: y
调度主机顺序#
利用队列参数resspec,您可以控制调度时选择主机的顺序。
- 例子1:作业调度到集群主机时,实现负载均衡。
AIP缺省的主机选择顺序是按照r15s:mem排序,即先按主机负载r15s排序,若r15s一样,再按 可用内存排序。这种排序是一个调度周期排一次,在同一个调度周期中,则是先把一台主机填满。 在作业少的情况下(一个调度周期内所有等待作业都能被调度和分发),作业调度就不能实现 真正的负载均衡。
在队列的参数中使用:resspec: order[slots]
这个参数让调度器在同一个调度周期中每个作业都对主机按其可用作业槽做一次排序,从而实现同 调度周期内的负载均衡。
- 例子2:尽量把作业往同一个主机上放,留出空间给大作业。比如尽量让AI训练任务用同一台主机上的8个GPU。
这个例子是典型的“去碎片化”。可以使用队列的参数:resspec: order[-slots]
这个参数让调度器尽量用可用作业槽数少的机器,把作业槽数多的机器留给大作业。
类似可以用:resspec: order[-gpu] 来让作业尽量跑在可用GPU数少的机器上。
大作业和独占作业作业槽预留#
大作业是指需要作业槽多的作业,这样的作业可以是单机,或者是跨机运行的。
由于调度器每次都去匹配队列中的作业资源需求与主机可用资源,小的作业比较容易找到可用的资源而往 往先被调度,这样导致大作业长期得不到所需的资源而等待。
通过配置队列参数:slotreservetime: N (N是保留的分钟数),调度器在小作业结束后会为队列中 的大作业保留空出的作业槽N分钟,从而增加大作业被调度的可能性。
如果过了保留时间还是没有足够的作业槽给大作业,所保留的作业槽会被释放,调度器进入新一轮的作业 槽预留。
最佳时间是slotreservetime为集群中的平均作业运行时长。
独占作业是指不管作业使用多少资源,作业必须独占一台或多台主机。这类作业不会被调度到 有作业运行的主机上,而一旦开始运行,所运行的主机上也不会再被调度其他作业。
队列中必须设置参数:exclusive: yes,用户才可以提交独占作业到这个队列中,提交的命令行为: “csub -x myjob”。
独占作业与大作业非常类似,在繁忙的集群中很难空出整台主机可以运行独占作业。队列参数**slotreservetime** 也可以启动独占作业的作业槽预留。
作业运行时长控制#
为了防止作业运行时应用异常但不退出,长期占用资源,队列中可以设置runlimit参数控制作业最长 运行时长。超过运行时限的作业会被调度器杀掉。
备注
在运行时限到达时,调度器向作业发送信号 SIGUSR2 (12),如果作业不退出,5分钟后或者 runaway_job_grace_period( cb.yaml )后,调度器连续发送SIGINT(2), SIGTERM(15), 和SIGKILL(9), 这些信号间隔为10秒或者 job_terminate_interval ( cb.yaml ), 最后所有作业进程都会被杀掉,包括多机作业上所有属于该作业的进程。
参数的单位为分钟。
例子:
queues:
- name: medium
runlimit: 1440 # 24 小时
备注
runlimit参数可以定义两个值,一个缺省,一个最大。具体使用参考 cb.yaml 。
作业内存使用控制#
当主机上的可用内存耗尽时,主机会挂掉,这样一个超用内存的作业会影响同一主机上的其他作业。
内存控制有以下几种场景:
- 企业内部集群用户无法预测作业所需内存
用户无法为作业预留内存(csub -R rusage[mem=xxx]),这种场景可以利用负载阈值的调度方法。
内存调度阈值可以定义在主机的配置里,或者定义在队列里。队列里定义的阈值是不能区分不同 主机的不同阈值的。
队列中定义阈值的队列参数是:thresholds。例子:
queues: - name: medium thresholds: - "mem 1G/0.5G"
第一个值表示:当主机内存小于这个值后,主机不再接受新的作业,不管主机上是否还有空的作业槽。
第二个值表示:当主机内存小于这个值后,主机上的作业会被暂停,以防主机挂掉。
也可以之选配第一个值,因为暂停作业不会释放内存,从而导致作业处于停顿状态。主机可以通过 使用交换区(SWAP)避免主机因内存而挂掉。
- 对外服务的计算中心严格控制作业内存使用
通过使用作业级的内存使用限制保证主机内存不会超载。超过内存限额的作业会被调度器杀掉。
推荐使用的参数为:memlimit: percore
这是根据作业所用核数来确定内存够使用限制。如主机总共56个核,内存总量为1T,则每个核的内存 限制为约18GB。一个16核(作业槽)的作业的内存限制是:288GB。
具体每个核的内存限制会因主机的硬件配置不同而不同。如果过一个作业跨多个主机,而每台主机 的硬件配置不同,调度器会按照作业运行的第一台主机的硬件配置计算相应的内存使用上限。
备注
调度器每15秒检查一次作业内存使用。检查时如果过发现作业所有进程,包括多台主机上的远程 进程使用内存的总核超过限制,调度器向作业发送信号SIGINT(2), SIGTERM(15), 和SIGKILL(9), 这些信号间隔为10秒或者 job_terminate_interval ( cb.yaml ), 最后所有作业进程都会被杀掉,包括多机作业上所有属于该作业的进程。