记账、配额实操与容量规划¶
执行日期:2026-09-11 | 集群:Slurm 26.05.2 + slurmdbd/MySQL 复现脚本:
./phase6_lab.sh quota|capacity相关文档:阶段6_进阶与对比.md | QOS抢占与优先级实操.md
一、记账体系与 TRES¶
1.1 关键配置(实测)¶
AccountingStorageType = accounting_storage/slurmdbd
AccountingStorageHost = k8s-master-01
AccountingStorageEnforce = associations,limits,qos
AccountingStorageTRES = cpu,mem,energy,node,billing,fs/disk,vmem,pages,
license/ads,license/ams_sim,license/assura_drc,license/assura_lvs,
license/calibredrc,license/calibrelvs,license/calibreperc,
license/calibrexact,license/calibrexrc,license/ncsim
AccountingStorageEnforce 三个维度的实测含义:
| 维度 | 强制内容 | 实测表现 |
|---|---|---|
associations |
未登记的 account/user 不能提交 | 未授权的 --qos= 直接拒绝 |
limits |
限额强制生效 | MaxTRESPU 生效(见第三节) |
qos |
QOS 授权与限额强制 | assoc 未授权 QOS → Invalid qos specification |
1.2 TRES 与 License 打通验证¶
$ scontrol show licenses
LicenseName=ads@27000@k8s-master-02
Total=8 Used=0 Free=8 Reserved=0 Remote=yes
LastConsumed=0 LastDeficit=0 LastUpdate=2026-09-10T14:00:10
LicenseName=ams_sim@27000@k8s-master-02
Total=8 Used=0 Free=8 Reserved=0 Remote=yes
这是本阶段确认的重要事实:Licenses= 与远程 FlexLM(k8s-master-02:27000)链路已真实打通,
14 项 EDA 工具 License 全部登记在 TRES 中且轮询正常(LastUpdate 分钟级)。
EDA 场景可基于此实现"License 感知调度"(QOS MaxTRESPU=license/ads=N 限额、--licenses=ads:2 申报)。
1.3 记账层次结构¶
Cluster(cluster)
└── Account(root) ── dev ── teama ── teama1 ── teamb ── teamb1 ── teamc ── teamc1 ── it ── ops
└── User(rain01/rain02/rain03/cloud01/cy01/david01/lws01/cq01/root)
└── Partition(interactive/compile/regression/long)
└── QOS(interactive/regression/normal/long)
实测 sacctmgr list assoc 摘要(17 条 association):
cluster|root|||normal|1
cluster|root|root||normal|1
cluster|dev|||interactive,long,normal,regression|1
cluster|teama|||interactive,long,normal,regression|1
cluster|teama|rain01||interactive,long,normal,regression|1
cluster|teama|rain02||interactive,long,normal,regression|1
cluster|teama|rain03||interactive,long,normal,regression|1
... (teama1/teamb/teamb1/teamc/teamc1/it/ops 同构)
注意 root 只授权 normal(唯一例外),业务用户均有 4 个 QOS。
二、sacctmgr 实操记录(含关键字陷阱)¶
2.1 备份(一切变更之前)¶
sacctmgr -i dump cluster file=/root/slurm_acct_backup_$(date +%Y%m%d).cfg
# 实测输出:逐条回显全部 account/user/QOS 定义,落盘 3153 字节
# 恢复参照:该文件可直接作为重建 association 的依据
ls -l /root/slurm_acct_backup_20260911.cfg
2.2 创建(本次实操命令与实测回显)¶
$ sacctmgr -i add qos t6lab Priority=30 MaxTRESPU=cpu=8 MaxJobsPU=2 MaxSubmitJobsPU=3
Adding QOS(s)
t6lab
Settings
Description = t6lab
MaxJobsPerUser = 2
MaxSubmitJobsPerUser = 3
MaxTRESPU = cpu=8
Priority = 30
$ sacctmgr -i add account t6lab Description="P6 lab temp" Organization=study
Associations =
C = cluster A = t6lab
$ sacctmgr -i add user root account=t6lab
Associations =
C = cluster A = t6lab U = root
2.3 两个实测踩坑¶
坑 1:MaxSubmitPU 不是设置关键字
$ sacctmgr -i add qos t6lab MaxSubmitPU=3
Unknown option: MaxSubmitPU=3 <- 整条命令中止,QOS 未被创建
| 列表显示字段 | 正确设置关键字 |
|---|---|
MaxSubmitPU |
MaxSubmitJobsPU |
MaxJobsPU |
MaxJobsPU |
MaxTRESPU |
MaxTRESPU=cpu=8 |
坑 2:授权 QOS 用 set qos= 会与 DefaultQOS 冲突
$ sacctmgr -i modify user where user=root account=t6lab set qos=t6lab
Error with request: This request would make it so some associations would not have access to their default qos.
Modified user associations... <- 但 assoc 实际未更新(QOS 仍为 normal)
正确写法(追加):
$ sacctmgr -i modify user where user=root account=t6lab set qos+=t6lab
$ sacctmgr -n -P list assoc where account=t6lab format=Account,User,QOS,DefaultQOS
t6lab|root|normal,t6lab|normal
2.4 查询与删除¶
# 查询(推荐用 format= 精简输出)
sacctmgr -n -P list qos format=Name,Priority,Preempt,PreemptMode
sacctmgr -n -P list assoc where account=t6lab format=User,QOS,DefaultQOS
scontrol show assoc_mgr qos=t6lab # slurmctld 内存中解析后的实时视图(含计数器)
# 删除(顺序:先关联,再账号/QOS)
sacctmgr -i delete user rain01 account=t6lab
sacctmgr -i delete user root account=t6lab
sacctmgr -i delete account t6lab
sacctmgr -i delete qos t6lab
scontrol show assoc_mgr是排障利器:它显示 slurmctld 内存中的限额值与实时计数,例如MaxJobsPU=2(4)表示"限额 2 / 当前 4"。判断"限额没生效"时,先看这里确认数据是否真的加载了。
三、限额实验(含缺陷 D4)¶
3.1 生效的限额:MaxTRESPU(TRES 类)¶
# 排队端拦截
$ sbatch -A t6lab --qos=t6lab -p compile -n12 --mem=20000M --wrap "sleep 60"
Submitted batch job 416
JOBID NAME USER QOS ST CPUS REASON
416 T6B_12C root t6lab PD 12 QOSMaxCpuPerUserLimit <- 限额 cpu=8,请求 12
# 给出 QOS 加 DenyOnLimit 后,升级为提交端硬拒
$ sacctmgr -i modify qos t6lab set flags=DenyOnLimit
$ sbatch -A t6lab --qos=t6lab -p compile -n16 --mem=60000M --wrap "sleep 60"
sbatch: error: QOSMaxCpuPerUserLimit
sbatch: error: Batch job submission failed: Job violates accounting/QOS policy (job submit limit, user's size and/or time limits)
| 拦截路径 | 触发条件 | 表现 |
|---|---|---|
| 排队端 | 单作业 TRES 请求超 MaxTRESPU |
PD + REASON=QOSMaxCpuPerUserLimit |
| 提交端 | QOS 带 Flags=DenyOnLimit |
立即失败 + Job violates accounting/QOS policy |
3.2 未生效的限额:MaxJobsPU / MaxSubmitJobsPU / assoc MaxJobs(缺陷 D4)¶
实验设计:QOS t6lab 设 MaxJobsPU=2、MaxSubmitJobsPU=3;association 再设 MaxJobs=1;由普通用户 rain01 提交。
实测结果(全部未被拦截):
t6lab|30|2|3|cpu=8 <- QOS 限额已正确存储
rain01|normal,t6lab|normal <- 授权正确
rain01|1|| <- association MaxJobs=1 已存储
421 T6A2_4 rain01 t6lab R 1 <- 第 4 个作业,MaxSubmitJobsPU=3 未拦截
418 T6A2_2 rain01 t6lab R 1
419 T6A2_3 rain01 t6lab R 1
417 T6A2_1 rain01 t6lab R 1
(MaxJobsPU=2 下 4 个作业同时 RUNNING)
scontrol show assoc_mgr 证明数据与计数均正确加载:
QOS=t6lab(7)
PreemptMode=OFF Priority=30
User Limits
rain01(2001)
MaxJobsPU=2(4) MaxJobsAccruePU=N(0) MaxSubmitJobsPU=3(4) <- 限额 2/3,计数 4/4
MaxTRESPU=cpu=8(4),mem=N(8192),...
已排除的原因:
| 假设 | 验证 | 结论 |
|---|---|---|
| 限额未加载到 slurmctld | scontrol show assoc_mgr 显示限额与计数均正确 |
排除 |
| 调度侧缓存陈旧 | scontrol reconfigure 后重测 |
排除(仍不拦截) |
| root 特权豁免 | 改用普通用户 rain01(AdminLevel=None) | 排除(同样不拦截) |
| 缺少 DenyOnLimit 标志 | 给 QOS 加 Flags=DenyOnLimit |
计数类仍不拦截(TRES 类被强化为硬拒) |
| 关键字写错 | sacctmgr list qos format=...MaxJobsPU... 回读为 2 |
排除 |
结论与建议:
- 本集群 TRES 类限额(cpu/mem)可靠可用,计数类限额(MaxJobsPU / MaxSubmitJobsPU / assoc MaxJobs)实测不生效;
- 生产上"限制并发/提交数"优先用 TRES 表达(如
MaxTRESPU=cpu=N),并加Flags=DenyOnLimit在提交端兜底; - 计数类限额如需使用,必须先在目标版本做受控验证(本报告已提供完整验证方法);
- D4 的精确代码路径未定位,建议向 Slurm 社区确认是否为 26.05 的已知行为(本报告按"现象+证据+已排除项"如实记录,不做主观归因)。
3.3 临时实体的完整回滚(本次已执行)¶
scancel $(squeue -h -o "%i")
sacctmgr -i delete user rain01 account=t6lab
sacctmgr -i delete user root account=t6lab
sacctmgr -i delete account t6lab
sacctmgr -i delete qos t6lab
# 校验
sacctmgr -n -P list qos format=Name,Priority,Preempt,PreemptMode # 回到 4 个基线 QOS
sacctmgr -n -P list assoc where account=t6lab # 空
sacctmgr -n -P list account where name=t6lab # 空
四、记账报表实操¶
4.1 作业明细(sacct)¶
$ sacct -j 427 -X -o JobID,JobName%12,Partition,Account,User,State,Elapsed,AllocCPUS,ReqMem,MaxRSS,ExitCode,NodeList
JobID JobName Partition Account User State Elapsed AllocCPUS ReqMem MaxRSS ExitCode NodeList
427 SLURM_SIDE compile teama rain01 COMPLETED 00:00:27 2 1G 0:0 k8s-node-01
常用字段与含义(本集群已实测):
| 字段 | 含义 | 备注 |
|---|---|---|
AllocCPUS |
实际分配 CPU 数 | 计费核心字段 |
ReqMem |
申请内存 | 后缀 c=per-CPU,n=per-Node |
MaxRSS |
峰值常驻内存 | 需 JobAcctGather 配置 |
ExitCode |
退出码 退出状态:信号 |
SEGV=0:11、命令不存在=127:0、OOM=0:125(阶段 5 已证实) |
Elapsed |
运行时长 | — |
4.2 聚合报表(sreport)¶
# 集群利用率(CPU 小时)
$ sreport cluster utilization start=2026-08-01 -t hours
Cluster Allocate Down PLND Dow Idle Planned Reported
cluster 124 7 0 9446 47 9625
注意:
sreport account utilization是无效写法,实测报invalid keyword: account。 正确写法为报告类型:sreport cluster AccountUtilizationByUser/AccountUtilizationByQOS/UserUtilizationByAccount/UserUtilizationByWckey/Utilization/WCKeyUtilizationByUser。
# 用户用量排行
$ sreport user topusage start=2026-09-01 topcount=10
Cluster Login Proper Name Account Partition Used
cluster rain01 rain01 teama eda 6669
cluster rain01 rain01 teama 673
cluster root root root 82
# 公平份额
$ sshare -a -o "Account,User,RawShares,RawUsage,EffectvUsage,FairShare"
Account User RawShares RawUsage EffectvUsage FairShare
root 1 127447 1.000000
root root 1 4559 0.035776 0.555556
dev 1 122887 0.964224
teama 1 122887 1.000000
teama rain01 1 33924 0.276064 0.111111
teama rain02 1 0 0.000000 0.333333
五、容量现状分析¶
5.1 物理容量¶
| 项 | 值 | 来源 |
|---|---|---|
| 计算节点 | 3 台(k8s-node-01/02/03) | sinfo |
| 单节点 CPU | 16 核(CoresPerSocket=1 × Sockets=16,ThreadsPerCore=1) | scontrol show node |
| 单节点内存 | 32010 MB(约 31.3 GB) | RealMemory |
| 集群总容量 | 48 CPU / 96030 MB(约 93.8 GB) | CfgTRES=cpu=16,mem=32010M |
| 可用分区时限 | interactive 4h / compile 24h(默认)/ regression 8h / long 72h | scontrol show partition |
| 特征标签 | intel, centos7, skx-16c | AvailableFeatures |
| GRES | (null) —— 无 GPU | scontrol show node |
5.2 利用率实测(严重低载)¶
| 统计区间 | Allocate | Idle | Planned | Down | 利用率 |
|---|---|---|---|---|---|
| 2026-08-01 ~ 09-11(含旧 EDA 分区时期) | 124 CPU·h | 9446 CPU·h | 47 | 7 | 1.29% |
| 2026-09-08 ~ 09-11(EDA 规范配置后) | 13 CPU·h | 3478 CPU·h | 13 | 0 | 0.37% |
注:
sreport的 Reported 合计(9625 / 3504 CPU·h)远小于理论值(48 CPU × 41 天 × 24h = 47232), 原因是期间发生过分区重构(旧EDA分区在 9/8 被 4 个新分区取代),历史数据跨了两套配置,报表口径不连续。 结论仍成立:当前集群处于严重低载状态(<1.5%)。
5.3 作业画像(2026-09-01 起,427 个已结束作业)¶
按分区分布:EDA(旧)=240 compile=134 long=23 interactive=15 regression=15
状态分布: COMPLETED=292 CANCELLED=103 FAILED=27 OUT_OF_MEMORY=3 TIMEOUT=2
(其中 "CANCELLED by 0"(50) 为本次阶段测试手动清理,非业务失败)
资源消耗: 总 129.4 CPU·h,平均时长 102.7 秒,最长 2604 秒(43 分钟)
排队情况: 平均排队 ≈ 0 秒(集群空闲,无排队压力)
作业形态特征:
- 绝大多数是短作业(平均 103 秒,最长 43 分钟),与
interactive(4h) /regression(8h) 的时限设定严重不匹配 long(72h) 分区 23 个作业 —— 实际负载中缺少长时任务,该分区基本空转- 失败构成:FAILED 27 + OOM 3 + TIMEOUT 2 = 32(占 7.5%),主要来自阶段 4/5 的故意构造场景
5.4 容量缺陷 D3:DefMemPerCPU 吃掉一核¶
DefMemPerCPU = 2048 MB
RealMemory = 32010 MB
默认可选核数 = floor(32010 / 2048) = 15 核(16 核需要 32768 MB > 32010 MB)
实测:
| 提交方式 | 结果 |
|---|---|
sbatch -N1 -n15(无 --mem) |
COMPLETED,ReqMem=30G,落在 k8s-node-02 |
sbatch -N1 -n16(无 --mem) |
FAILED:Batch job submission failed: Requested node configuration is not available |
sbatch -N1 -n16 --mem=31000M |
COMPLETED,ReqMem=31000M,落在 k8s-node-01 |
影响量化:
- 每节点 1 核(16-15)无法通过默认路径使用 → 集群 3/48 = 6.25% 的算力被配置浪费
- EDA 工具常按核授权(如 16 核满节点跑一个 tool),此类作业100% 提交失败,用户被迫改写命令
修复建议(按优先级):
# 方案 1(推荐,最小改动):调整 DefMemPerCPU 到 2000,使 16×2000=32000 ≤ 32010
DefMemPerCPU=2000
# 方案 2:用户侧显式声明内存(已实测可行,但依赖规范约束)
sbatch -N1 -n16 --mem=31000M ...
# 方案 3:同时核对 MaxMemPerCPU,避免与 DefMemPerCPU 冲突
六、容量规划与生产最佳实践¶
6.1 容量规划建议¶
| 结论 | 依据 | 建议动作 |
|---|---|---|
| 算力严重过剩 | 利用率 0.37%~1.29% | 承接更多 EDA 业务,或评估缩容(保留 3 节点以容纳多节点作业) |
| 时限配置与真实负载错配 | 平均作业 103 秒 vs 分区时限 4h~72h | 保留 interactive 4h;long 72h 可下调(当前空转);可增设 5~15 分钟的 fast 分区承接短作业 |
| 单节点可调度核数被内存默认值限制 | D3:15/16 核可用 | 改 DefMemPerCPU=2000,回收 6.25% 算力 |
| 无 GPU | GRES=(null) | EDA 若引入 GPU 加速工具,需先规划节点与 gres.conf(阶段 3 已做模拟推演) |
| License 与算力解耦 | 14 项 FlexLM License 已联通,单工具 8 席 | 用 QOS MaxTRESPU=license/xxx 做 License 感知限额,避免"有核无 License"空跑 |
| 双调度器并存 | LSF 20 slot/节点 vs Slurm 16 CPU/节点 | 迁移需按 6.2 做容量重估,不能 1:1 换算 |
6.2 生产最佳实践清单(含阶段 3/5/6 全部发现)¶
提交侧
- EDA 提交模板必须显式带
--qos=(否则按 D1 全部落 normal,分级失效); - 满节点作业显式
--mem=(规避 D3),或先修DefMemPerCPU; - 短作业走
interactive/新增快速分区,长作业走long,避免大作业占满长时限分区; - License 作业申报
--licenses=<tool>:<n>,让调度器做 License 感知排队。
配置侧
PreemptExemptTime=30min对交互场景偏长,建议在interactiveQOS 上单独设更短值(QOS 级优先于全局);SchedulerParameters中的sched_min_age=30疑似无效参数(man 页无此子项),建议清理,避免"以为配了";SchedulerParameters含defer:单作业提交不会立即调度,追求低延迟需评估是否移除;- 抢占配置不能用配置值验收,必须做端到端抢占实测(D2 教训);
- 限额配置优先用 TRES 类(D4 教训),计数类须受控验证;
StateSaveLocation避免放在慢速存储(阶段 3 已记录)。
运维侧
- 变更前必备份(
cp -a slurm.conf slurm.conf.bak.<date>+sacctmgr dump),本次已形成标准动作; - QOS/association 变更后用
scontrol show assoc_mgr复核数据是否真的加载; - 节点维护先
DRAIN后停服务(阶段 5 教训:systemctl stop slurmd会因KillMode=control-group连坐清杀作业); - munge 密钥纳入 CMDB 基线(md5
318fd0afb38e9279a68523a455d964b5),三节点一致性定期校验。
6.3 巡检清单(建议节奏)¶
每日
systemctl is-active slurmctld slurmdbd munge # 服务存活
sinfo -o "%20P %6D %6t" # 分区与节点状态(有无 down/drain)
squeue -o "%.6i %.10P %.2t %r" # 队列健康(有无异常 PD 堆积)
sdiag | head -20 # 调度器循环是否正常
scontrol show licenses | grep -c "Free=0" # License 是否耗尽
每周
sreport cluster utilization start=$(date -d '7 days ago' +%F) -t hours # 利用率趋势
sreport user topusage start=$(date -d '7 days ago' +%F) topcount=10 # 用量排行
sshare -a # 公平份额与累计用量
sacct -S $(date -d '7 days ago' +%F) -X -o State -n | sort | uniq -c # 失败率趋势
sacct -S $(date -d '7 days ago' +%F) -X -o JobID,Partition,QOS,State # QOS 落点抽检(D1 防御)
每月
sacctmgr dump cluster file=/root/slurm_acct_backup_$(date +%Y%m%d).cfg # 记账库备份
# 三节点 munge 一致性
for n in 01 02 03; do ssh k8s-node-$n "md5sum /etc/munge/munge.key"; done
# 配置基线一致性(与备份比对 md5)
md5sum /usr/local/slurm/etc/slurm.conf
# 抢占链路端到端验证(D2 防御,见 QOS抢占与优先级实操.md 第八节)
七、变更与回滚记录(本次实操)¶
| 变更 | 基线 | 已回滚 | 回滚命令 |
|---|---|---|---|
临时 QOS/account/assoc t6lab |
不存在 | 是 | sacctmgr -i delete qos t6lab / delete account t6lab / delete user <u> account=t6lab |
QOS long PreemptMode |
suspend |
是 | sacctmgr -i modify qos long set preemptmode=suspend |
slurm.conf PreemptExemptTime |
00:30:00 |
是 | cp -a /usr/local/slurm/etc/slurm.conf.bak.p6.preempt.20260911_120547 /usr/local/slurm/etc/slurm.conf && scontrol reconfigure |
备份文件:
/root/slurm_acct_backup_20260911.cfg # 记账库全量导出
/usr/local/slurm/etc/slurm.conf.bak.p6.20260911_120306 # md5=1cdcc770022d0d65f49d42a565e443de
/usr/local/slurm/etc/slurm.conf.bak.p6.preempt.20260911_120547 # 含 PreemptExemptTime=00:30:00
终检:4 个基线 QOS 完整(normal 20/requeue、interactive 100 Preempt=long,normal/requeue、regression 50/cluster、long 10/suspend);
t6lab 无残留;队列空;12 个 node-partition 组合全 idle;slurm.conf md5 与备份一致。
来源:
/home/rain/Documents/slurm/slurm_study/slurm_study_plan/阶段6_进阶与对比/记账配额与容量规划.md| 最后更新:2026-09-11 12:31(由build/sync.py同步,请勿在站点侧修改)