OpenLava 完全入门(三):队列与资源管理

OpenLava 完全入门(三):队列与资源管理

摘要:队列(Queue)是 OpenLava 调度的核心概念,资源(Resource)是调度决策的依据。本文详细讲解队列配置语法、8 种队列控制策略、自定义资源定义(布尔型/数值型/可消耗型)、内存与 GPU 资源管理、license 资源调度,以及资源需求表达式 `-R` 的完整语法。读完你能根据业务需要灵活规划和配置集群。

上一篇我们讲了作业管理命令。这一篇深入队列和资源——OpenLava 调度的两个核心支柱。


零、读前必看

0.1 适合谁

  • ✅ 已经会提交作业,想搞懂调度背后的机制
  • ✅ 需要根据业务划分队列、管理资源
  • ✅ 想配置 GPU / license 等特殊资源

0.2 你需要的权限

  • 修改配置文件需要集群管理员权限(lsf 用户或 root)
  • 改完配置需要 badmin reconfig 重新加载

一、队列(Queue)基础

1.1 队列是什么

**队列就是作业的分类桶。** 不同业务、不同优先级、不同类型的作业放进不同队列,调度器按队列的规则来处理。
  作业提交 → 进入某个队列 → 按队列规则调度 → 分配到计算节点
              │
              ├── normal 队列(普通作业,优先级 30)
              ├── short 队列(短作业,优先级 40,30 分钟上限)
              ├── high 队列(紧急任务,优先级 50)
              └── debug 队列(调试用,只能跑 10 分钟)

1.2 队列能控制什么

控制项 关键字 说明
优先级 PRIORITY 数字越大越优先
运行上限 RUNLIMIT 单个作业最长运行时间
作业数量 QJOB_LIMIT 队列同时运行的作业总数上限
单用户上限 UJOB_LIMIT 每个用户在该队列最多同时跑多少
单主机上限 PJOB_LIMIT 每台主机在该队列最多跑多少
允许用户 USERS 谁可以提交
允许主机 HOSTS 可以用哪些节点
Nice 值 NICE 进程 nice 值,影响本地调度优先级
调度窗口 DISPATCH_WINDOW 什么时间段才调度
抢占 PREEMPTION 能不能抢占低优先级队列

1.3 一个完整的队列配置

Begin   Queue
QUEUE_NAME      = normal
PRIORITY        = 30
NICE            = 20
QJOB_LIMIT      = 200
UJOB_LIMIT      = 50
PJOB_LIMIT      = 10
RUNLIMIT        = 72:00          # 72 小时上限
DISPATCH_WINDOW =  ()            # 一直可调度
# DISPATCH_WINDOW =  20:00-08:00  # 只有晚上 8 点到早上 8 点才跑
HOSTS           = compute01 compute02 compute03
USERS           = all
FAIRSHARE       = USER_SHARES[[default,1]]
End     Queue
配置文件在 `/opt/openlava/etc/lsb.queues`。

二、队列配置详解

2.1 优先级 PRIORITY

PRIORITY = 30
  • 数字越大,优先级越高
  • 默认队列优先级范围 1-100
  • 高优先级队列的 PEND 作业会被优先调度
  • 配合 PREEMPTION 可以抢占低优先级作业(后面讲)

生产建议

队列 优先级 用途
debug 60 调试,快速响应
high 50 紧急任务
short 40 短作业(< 30 分钟)
normal 30 日常作业
low 20 低优先级长任务

2.2 运行上限 RUNLIMIT

RUNLIMIT = 30            # 30 分钟
RUNLIMIT = 2:00          # 2 小时
RUNLIMIT = 72:00         # 72 小时(3 天)
超过运行时限的作业会被自动杀掉。短作业队列设短一点,防止资源被长时间占用。

2.3 作业数量限制

QJOB_LIMIT = 200         # 队列同时 RUN 状态作业上限
UJOB_LIMIT = 50          # 每个用户最多同时跑 50 个
PJOB_LIMIT = 10          # 每台机器最多跑 10 个本队列作业

为什么需要这些限制?

  • 防止一个用户把所有资源占满(公平性)
  • 防止队列之间互相影响(稳定性)
  • 防止某台机器被打爆(节点保护)

2.4 用户和主机限制

USERS = all                                   # 所有用户
USERS = user1 user2 user3                     # 指定用户
USERS = user1 user2 /group1                   # 用户 + 用户组
USERS = all !bad_user                         # 除了 bad_user

HOSTS = compute01 compute02                   # 指定主机
HOSTS = all                                   # 所有主机
HOSTS = compute+                              # 主机名以 compute 开头的
HOSTS = compute01 compute02 !compute03        # 排除 compute03

2.5 调度窗口 DISPATCH_WINDOW

DISPATCH_WINDOW = ()                            # 始终可调度
DISPATCH_WINDOW = 20:00-08:00                    # 每天晚 8 点到早 8 点
DISPATCH_WINDOW = 18:00-09:00 Sat Sun            # 工作日晚上 + 周末全天
**典型用法**:白天跑关键业务,晚上跑批处理。低优先级作业只在闲时运行。

2.6 FAIRSHARE(公平分享)

FAIRSHARE = USER_SHARES[[default,1]]
FAIRSHARE = USER_SHARES[[user1,10] [user2,5] [default,1]]

作用:当多用户同时排队时,按份额分配资源,避免一个用户占满所有资源。

  • [user1,10] 表示 user1 有 10 份份额
  • [default,1] 表示其他用户默认 1 份
  • 份额越大,分到的资源越多

2.7 PREEMPTION(抢占)

# 在高优先级队列里配置
PREEMPTION = PREEMPTIVE

# 被抢占的队列配置
PREEMPTION = PREEMPTABLE

工作机制:高优先级队列作业来了,低优先级正在运行的作业被挂起/杀掉,让出资源。

抢占类型

类型 含义
PREEMPTIVE 这个队列可以抢占其他队列
PREEMPTABLE 这个队列可以被抢占
**慎用抢占**。抢占会中断正在运行的作业,如果作业不支持 checkpoint,前面跑的时间就白费了。

2.8 队列状态

# 查看所有队列状态
bqueues
# QUEUE_NAME      PRIO STATUS          MAX JL/U JL/P JL/H NJOBS  PEND   RUN  SUSP
# normal           30  Open:Active       -  100    -    -    25    10    15     0
# short            40  Open:Active       -   50    -    -     5     2     3     0

状态说明

状态 含义
Open:Active 正常,可提交可调度
Open:Inactive 可提交,但不调度(作业会 PEND)
Closed:Active 不接受新提交,但已有的继续调度
Closed:Inactive 既不接受也不调度

管理员操作

# 关闭队列(不让提交新作业)
badmin qclose normal

# 打开队列
badmin qopen normal

# 暂停调度(已提交的不调度了)
badmin qinact normal

# 恢复调度
badmin qact normal

三、资源(Resource)管理

3.1 资源是什么

**资源是作业调度的"货币"**。作业说"我要 4 核 CPU + 8G 内存 + 1 张 GPU",调度器找满足条件的节点分配。

OpenLava 里的资源分几类:

类型 例子 说明
内置资源 ncpusmemswaptmp 每个节点自动有
布尔型资源 gpuhighmemhas_license 要么有要么没有
数值型资源 gpu_num=2license=10 数量可计数
可消耗资源 licensetokens 作业占用一份就少一份
固定资源 ncpusmem 节点属性,不会减少

3.2 内置资源

每个节点自动采集的:

资源名 含义 单位
ncpus CPU 核数
ncpu CPU 核数(旧名称)
mem 可用内存 MB
swp 可用交换空间 MB
tmp /tmp 可用空间 MB
r15s / r1m / r15m 15秒/1分钟/15分钟平均负载 -
ut CPU 利用率 %
pg 分页速率 -
io IO 速率 -
ls 登录用户数
it 空闲时间 分钟

3.3 查看节点资源

# 查看所有节点负载
lsload
# HOST_NAME       status  r15s   r1m  r15m   ut    pg  ls    it   tmp   swp   mem
# compute01        ok     0.0   0.0   0.0   1%   0.0   1    12   50G   64G   32G

# 查看节点详细资源
lshosts -l compute01

# 查看所有资源定义
lsinfo -r

四、自定义资源

4.1 定义资源

编辑 /opt/openlava/etc/lsf.shared

Begin   Resource
RESOURCENAME  TYPE    INTERVAL  INCREASING  CONSUMABLE  DESCRIPTION
# 布尔型
gpu           Boolean 60        N           N           (has gpu)
highmem       Boolean 60        N           N           (high memory node)
vcs_license   Boolean 60        N           N           (has vcs license)
# 数值型(可消耗)
gpu_num       Numeric 60        N           Y           (number of gpus)
license_a     Numeric 60        N           Y           (license a count)
End     Resource

字段说明

字段 含义
RESOURCENAME 资源名,字母数字下划线
TYPE BooleanNumeric
INTERVAL 采集间隔(秒)
INCREASING 值越大越好(Y)还是越小越好(N)。越大越好:数值高代表资源充足(mem)。越小越好:负载低好(r1m)
CONSUMABLE 是否可消耗。Y=作业用了就减少,跑完归还。比如 license、GPU
DESCRIPTION 描述,括号里是简称

4.2 给节点分配资源

编辑 /opt/openlava/etc/lsf.cluster.openlava

Begin   Host
HOSTNAME    model    type    server  r1m  mem   swp    RESOURCES
compute01   IntelI7  linux   1       3.5  32G   64G    (compute gpu gpu_num=2)
compute02   IntelI7  linux   1       3.5  32G   64G    (compute gpu gpu_num=2)
compute03   IntelI7  linux   1       3.5  128G  256G   (compute highmem)
compute04   IntelI7  linux   1       3.5  64G   128G   (compute gpu gpu_num=4 license_a=5)
End     Host

布尔型:写在括号里,出现就表示有:(gpu highmem) 数值型gpu_num=2 表示有 2 个 GPU 资源

4.3 动态资源(通过脚本采集)

有些资源是动态变化的(比如 license 剩余数量),可以通过外部脚本采集。

  1. 写采集脚本(输出 resource_name value):
#!/bin/bash
# /opt/openlava/scripts/collect_license.sh
# 模拟采集 license 数量
echo "license_a $(/opt/flexlm/lmstat -a | grep 'Total licenses' | awk '{print $4}')"
  1. lsf.shared 里定义:
Begin   Resource
RESOURCENAME  TYPE    INTERVAL  INCREASING  CONSUMABLE  DESCRIPTION
license_a     Numeric 60        N           Y           (license a count)
End     Resource
  1. lsf.cluster 里配置采集:
Begin   ResourceMap
RESOURCENAME  LOCATION
license_a     [default]
End     ResourceMap
  1. lsf.conf 里配置外部采集脚本(不同版本位置可能不同)。
**生产常用**:EDA license 数量就是典型动态资源,通过 `lmstat` 采集。

4.4 让配置生效

# 重新加载 LIM 配置(资源相关)
lsadmin reconfig

# 重新加载 batch 配置(队列相关)
badmin reconfig

五、资源需求表达式 -R

作业提交时用 -R 告诉调度器你需要什么资源。

5.1 基本用法

# 需要 4 核 + 4G 内存
bsub -n 4 -R "rusage[mem=4096]" command

# 需要 GPU 节点
bsub -R "gpu" command

# 需要 2 张 GPU
bsub -R "rusage[gpu_num=2]" command

# 需要高内存节点
bsub -R "highmem" command

5.2 rusage 详解

rusage 声明作业实际消耗的资源量:

rusage[mem=8192, gpu_num=1, license_a=2]

注意 mem 单位是 MB

# 每核 4G 内存,4 核一共 16G
bsub -n 4 -R "rusage[mem=4096]" command

# 作业总共用 16G 内存(per_job 关键字)
bsub -n 4 -R "rusage[mem=16384, per_job]" command

5.3 选择条件

# 选内存 > 32G 的节点
bsub -R "select[mem>32768]" command

# 选有 GPU 的节点
bsub -R "select[gpu]" command

# 组合条件:高内存 + GPU
bsub -R "select[highmem && gpu]" command

# 排除某节点
bsub -R "select[hname != compute01]" command

5.4 排序

# 按可用内存从大到小选节点
bsub -R "order[mem]" command

# 按负载从小到大选
bsub -R "order[r15m]" command

# 组合:先选有 GPU 的,再按 GPU 数量从多到少
bsub -R "select[gpu] order[gpu_num]" command

5.5 完整语法

bsub -R "select[条件] order[排序] rusage[消耗量] span[分布]" command
子句 作用 示例
select[...] 筛选符合条件的节点 select[mem>8192 && gpu]
order[...] 对筛选后的节点排序 order[mem](内存从大到小)
rusage[...] 声明作业消耗多少 rusage[mem=4096, gpu_num=1]
span[...] 控制跨节点分布 span[hosts=1](只在一台机器上)

5.6 span 子句(并行作业分布)

# 4 核都在同一台机器上(OpenMP 共享内存用)
bsub -n 4 -R "span[hosts=1]" command

# 4 核分布在 2 台机器上(MPI 跨节点用)
bsub -n 4 -R "span[hosts=2]" command

# 每台机器最多 2 核
bsub -n 8 -R "span[ptile=2]" command

5.7 资源需求示例

# 1. 普通 CPU 作业,每核 2G 内存
bsub -n 4 -R "rusage[mem=2048]" ./cpu_job

# 2. GPU 作业,要 1 张 GPU
bsub -n 2 -R "select[gpu] rusage[gpu_num=1, mem=8192]" ./gpu_job

# 3. 大内存作业,要 64G 内存的节点,总共占 64G
bsub -n 8 -R "select[mem>65536] rusage[mem=8192, per_job]" -R "span[hosts=1]" ./bigmem_job

# 4. EDA 作业,需要 5 个 license
bsub -R "rusage[license_a=5]" ./eda_job

# 5. 排除某台坏节点
bsub -R "select[hname != compute02]" ./job

# 6. 指定机型
bsub -R "select[model == IntelI7]" ./job

六、常见资源配置场景

场景 1:GPU 节点管理

# lsf.shared
Begin   Resource
RESOURCENAME  TYPE    INTERVAL  INCREASING  CONSUMABLE  DESCRIPTION
gpu           Boolean 60        N           N           (has gpu)
gpu_num       Numeric 60        N           Y           (gpu count)
gpu_mem       Numeric 60        N           N           (gpu memory MB)
End     Resource
# lsf.cluster
Begin   Host
HOSTNAME    model    type    server  r1m  mem   swp    RESOURCES
gpu01       NVIDIA   linux   1       5.0  128G  256G   (gpu gpu_num=4 gpu_mem=81920)
gpu02       NVIDIA   linux   1       5.0  128G  256G   (gpu gpu_num=8 gpu_mem=163840)
cpu01       IntelI7  linux   1       3.5  32G   64G    ()
End     Host

提交 GPU 作业:

# 要 2 张 GPU、32G 显存
bsub -R "select[gpu && gpu_mem >= 16384] rusage[gpu_num=2, mem=16384]" ./train.sh

场景 2:License 调度

# lsf.shared
Begin   Resource
RESOURCENAME  TYPE    INTERVAL  INCREASING  CONSUMABLE  DESCRIPTION
synopsys_vcs  Numeric 60        N           Y           (vcs license count)
cadence_ius    Numeric 60        N           Y           (ius license count)
End     Resource
# lsf.cluster
Begin   ResourceMap
RESOURCENAME  LOCATION
synopsys_vcs  [all]
cadence_ius   [all]
End     ResourceMap
license 是集群级资源,不绑定到具体节点。配合外部采集脚本动态更新。

提交 EDA 作业:

bsub -R "rusage[synopsys_vcs=1]" vcs -f filelist.f

场景 3:大小内存节点分流

# lsf.cluster
Begin   Host
HOSTNAME    model    type    server  r1m  mem    swp    RESOURCES
bigmem01    IntelI7  linux   1       3.5  512G   1T     (highmem)
bigmem02    IntelI7  linux   1       3.5  512G   1T     (highmem)
std01       IntelI7  linux   1       3.5  64G    128G   ()
std02       IntelI7  linux   1       3.5  64G    128G   ()
End     Host
# lsb.queues
Begin   Queue
QUEUE_NAME   = bigmem
PRIORITY     = 30
HOSTS        = bigmem01 bigmem02
RESOURCE_REQ = select[highmem]
USERS        = all
End     Queue

七、查看资源使用情况

# 1. 节点负载
lsload
lsload -l          # 详细
lsload -R "gpu"    # 只看有 GPU 的

# 2. 资源定义
lsinfo -r

# 3. 主机属性
lshosts
lshosts -l compute01

# 4. 队列槽位使用
bhosts
# HOST_NAME          STATUS       JL/U    MAX  NJOBS    RUN  SSUSP  USUSP    RSV
# compute01          ok              -      8      5      5      0      0      0

# 5. 资源使用统计
busers
# 看用户资源使用情况

# 6. 队列状态
bqueues -l normal

八、配置修改流程(生产规范)

  1. 备份配置
cp /opt/openlava/etc/lsb.queues /opt/openlava/etc/lsb.queues.bak.$(date +%F)
  1. 编辑配置文件
  2. 检查配置语法
badmin ckconfig
# Checking configuration files ...
# No errors found.
  1. 重新加载
# 队列等 batch 配置
badmin reconfig

# 资源等 LIM 配置
lsadmin reconfig
  1. 验证
bqueues -l new_queue
lsinfo -r | grep new_resource

九、常见问题

Q1:作业一直 PEND,说资源不足怎么办?

# 第一步:看 PEND 原因
bjobs -p <jobid>

# 第二步:看节点资源够不够
lsload -l

# 第三步:看是不是槽位满了
bhosts

Q2:mem 不够,加物理内存后怎么更新?

# 重启 LIM 重新采集
lsadmin limrestart all

# 或者自动会更新(看 INTERVAL 设置,默认几分钟)

Q3:如何临时让一个节点不接新作业?

# 关闭节点(不再接新作业,已有作业继续跑)
badmin hclose compute01

# 打开
badmin hopen compute01

# 彻底关闭(停掉 sbatchd)
badmin hshutdown compute01

Q4:如何查看某类资源还剩多少?

# 看所有节点的 GPU
lsload -R "gpu" | head

# 看 GPU 数量排名
lsload -l | grep gpu_num | sort

十、写在最后

队列和资源是 OpenLava 调度的两个核心:

  • 队列管"作业怎么排队"(优先级、限额、公平性)
  • 资源管"作业在哪跑"(CPU、内存、GPU、license)

把这两个搞清楚,集群规划就有谱了。

下一篇我们讲高级功能:并行作业(MPI)、作业依赖、作业数组、作业数组依赖、FairShare 详细配置、作业钩子(esub/epsub)等。


你的集群有几种队列?怎么划分的? 评论区聊聊,互相借鉴。

OpenLava #LSF #队列 #资源调度 #GPU #license #HPC #运维

发表回复

后才能评论