☰
Slurm 19.05.5 作业提交实战:srun、sbatch、salloc 三种模式与避坑指南
2026/10/23 5:07:58 网站建设 项目流程

简介:这份《国科大超算中心Slurm作业调度系统使用指南》面向高校与科研机构中需要在高性能计算集群上提交、管理作业的师生及工程师,尤其适合刚接触超算平台、希望系统掌握Slurm调度工具的入门与进阶用户。资源为一份PDF格式用户手册,压缩包内共1个文件,体积约595KB,轻量便携,便于随时查阅。手册内容覆盖Slurm基本概念与三种模式区别、常用用户命令与术语,并逐项讲解sinfo查看队列节点、squeue查看作业、scontrol show partition/node/job查看详细分区与作业信息、speek查看屏幕输出等操作;同时系统梳理srun交互式并行作业、sbatch批处理作业、salloc分配式作业三类提交方式,涉及串行、OpenMP共享内存、MPI并行及GPU作业提交,以及sbcast文件同步、sattach作业步吸附等进阶用法。目前已有3353人学习下载,适合作为超算上机实操的案头参考,帮助读者快速定位命令参数、理解作业提交流程与排错思路。

1. 从登录节点跑崩集群说起:Slurm 19.05.5 环境到底怎么装

刚接手一套高性能计算集群那会儿,我干过一件现在想起来还冒冷汗的事:把一段 MPI 测试程序直接在登录节点上mpirun跑了起来。几十个进程瞬间把登录节点的 CPU 吃满,同组几个正在编译代码的人终端直接卡死,管理员在群里连发三条消息问谁在登录节点跑作业。那次之后我才老老实实去翻这套 Slurm 作业调度系统的用户指南,把「什么命令在哪个节点跑、资源怎么申请、作业怎么提交」从头理了一遍。

这套环境在国内超算场景里非常常见:Slurm 19.05.5,装在/usr等系统默认目录,用户侧无需自己编译安装,登录后sinfo、squeue、sbatch这些命令直接可用。但「命令能用」和「会用」是两回事——三种提交模式(srun交互式、sbatch批处理、salloc分配式)选错,轻则排队几小时不动,重则作业被系统杀掉、机时白烧。这篇笔记面向刚拿到超算账号、准备跑第一个作业的开发者,也面向从 PBS、LSF 迁过来、需要快速对齐 Slurm 命令习惯的熟手。下面按「先认清环境 → 再配提交脚本 → 最后验证跑通」的顺序走一遍,每一步都给可抄的命令和参数取舍。

2. 认清 Slurm 环境:sinfo 与 squeue 先把家底摸清

装任何东西之前先看环境,这是运维的基本习惯。Slurm 用户侧不需要「安装」,但需要「确认可用队列、节点状态、自己的作业在哪」。这一步做扎实,后面提交作业才不会因为选错队列被卡在Resources状态。

2.1 用 sinfo 确认可用队列和节点状态

登录之后第一件事不是写脚本,是看系统现在有什么队列、哪些节点空闲。指南里给的命令是sinfo -l,我一般还会加-N看单节点粒度:

# 查看所有队列的概要信息,-l 输出详细信息 sinfo -l # 以每行一个节点的方式显示,方便看具体哪些节点空闲 sinfo -N # 只看某个队列,比如 GPU 队列 sinfo -p GPU-V100 # 按队列名升序、内存降序排序 sinfo -S +P,-m

sinfo -l的输出里几个字段必须看懂:PARTITION是队列名,带*的是默认队列;AVAIL为up表示可用,down表示不可用;TIMELIMIT是墙上时间限制,infinite表示不限;NODES是节点数;STATE是节点状态,idle空闲可接新作业,mixed表示部分 CPU 核在跑作业但还有空闲核,allocated表示已占满,down表示宕机。NODELIST是节点名列表,形如cnode[001-720]表示 cnode001 到 cnode720 这一批。

参数上,-p指定队列,-N按节点展开,-S排序(字段前+升序、-降序),-t按状态过滤(如-t idle只看空闲节点),-i可以每隔几秒自动刷新。我一般排查「为什么我的作业一直排队」时,会先sinfo -p 队列名 -t idle看目标队列到底有没有空闲节点,没有的话排队就是正常的,不是脚本写错了。

2.2 用 squeue 看作业状态和排队原因

作业提交出去之后,squeue是看得最频繁的命令。默认输出里ST字段是状态:PD排队中、R运行中、CG完成中、CD已完成、F失败、TO超时。NODELIST(REASON)这一列最关键——排队时它会告诉你卡在什么原因上。

# 查看当前队列中所有作业 squeue # 只看自己的作业 squeue -u $USER # 只看某个作业号 squeue -j 75 # 显示作业开始时间,方便判断还要等多久 squeue --start # 不显示表头,方便脚本解析 squeue -h -u $USER

常见的排队原因里,Resources表示在等资源(节点被占满),Priority表示有更高优先级作业在前面,Dependency表示在等依赖作业结束,PartitionNodeLimit表示申请的节点数超过队列限制,QOSResourceLimit表示达到 QOS 资源上限。看到Resources别急着改脚本,先sinfo确认队列是不是真的满了;看到PartitionNodeLimit才是脚本参数写大了,得回去改-N。

squeue的-o/--format参数支持自定义输出字段,比如squeue -o "%.8i %.9P %.20j %.8u %.2t %.10M %.6D %R",字段含义和sinfo的格式化类似,%i作业号、%P队列、%j作业名、%t状态、%M已运行时间、%D节点数、%R原因。熟手一般会把这行存成 alias,省得每次敲。

2.3 用 scontrol show 看详细节点与作业信息

概要信息不够用时,scontrol show是查细节的入口。它支持node、partition、job三类实体:

# 查看某个节点的详细信息 scontrol show node cnode001 # 查看某个队列的详细配置 scontrol show partition GPU-V100 # 查看某个作业的详细信息 scontrol show job 75 # 所有信息显示在同一行,方便 grep scontrol show job 75 --oneline

scontrol show node会输出节点的 CPU 数、内存、状态、正在跑的作业等;scontrol show partition会输出队列的时间限制、最大节点数、允许的 QOS 等;scontrol show job会输出作业的完整参数、分配到的节点、运行目录、环境变量等。排查「作业为什么被分配到这几个节点」时,scontrol show job里的NodeList和NumNodes是最直接的证据。

提示:scontrol不仅能看,还能改。scontrol update可以修改作业信息,但用户一般只能改自己的作业,且改之前最好先scontrol show job确认当前值,避免改错。

3. 三种提交模式怎么选:srun、sbatch、salloc 的配置与落地

环境摸清之后,核心问题来了:作业到底用哪个命令提交。指南里明确区分了三种模式,选错模式是新手最常见的翻车点。这一章把三种模式的适用场景、参数配置和可抄脚本讲透。

3.1 srun 交互式:短时间测试用,别拿来跑长作业

srun是交互式提交,资源分配和任务加载两步都通过它完成。执行srun后,它会先向系统提交资源请求并等待分配,然后在分配到的节点上加载任务,任务结束才返回终端。适合短时间、小规模的功能测试。

# 申请 2 个节点、每节点 4 个任务,运行 hostname srun -N 2 -n 8 hostname # 申请 1 个节点、4 个 CPU 核,运行 MPI 程序 srun -N 1 -n 4 ./my_mpi_app # 带 label 输出,每行前面标记是哪个任务输出的 srun --label -n 4 hostname

参数上,-N是节点数,-n是任务数(一般一个任务对应一个 CPU 核),--label让输出带任务标记,-p指定队列,-t指定时间限制。srun的关键限制是:提交时的终端断开,任务就终止。所以它只能用于短时间测试,长作业必须用sbatch。我见过有人用srun跑一个几小时的计算,结果网络一抖 SSH 断线,几小时机时直接打水漂。

3.2 sbatch 批处理:生产作业的标准姿势

sbatch是最常用的方式。提交后立即返回终端,作业被调度运行后在分配的首个节点上执行脚本,提交终端关掉也不影响作业运行。生产作业一律用这个。

一个典型的作业脚本长这样:

#!/bin/bash #SBATCH --job-name=my_test # 作业名 #SBATCH --partition=CPU-Large # 队列名,按 sinfo 实际结果填 #SBATCH --nodes=2 # 节点数 #SBATCH --ntasks-per-node=16 # 每节点任务数 #SBATCH --time=02:00:00 # 墙上时间限制,2 小时 #SBATCH --output=%j.out # 标准输出文件,%j 为作业号 #SBATCH --error=%j.err # 标准出错文件 module load intel/2019 # 按集群实际模块名加载 export OMP_NUM_THREADS=1 srun ./my_mpi_app # 在分配的资源上启动并行任务

提交用sbatch my_job.sh,提交后会返回一个作业号。脚本里的#SBATCH行是给 Slurm 看的参数,等价于命令行参数。--output和--error里的%j会被替换成作业号,方便区分不同作业的输出。--time格式是days-hours:minutes:seconds,只写HH:MM:SS也可以。

针对不同并行类型,脚本写法有差异。OpenMP 共享内存作业一般申请单节点多核,设OMP_NUM_THREADS等于申请的核数;MPI 作业用srun启动,任务数由--ntasks或--ntasks-per-node控制;GPU 作业需要--gres=gpu:数量申请 GPU 资源,并在脚本里确认CUDA_VISIBLE_DEVICES环境变量。指南里专门有一节讲「作业获取的节点名及对应 CPU 核数解析」,核心是让脚本能拿到SLURM_NODELIST、SLURM_NTASKS这些环境变量,动态适配分配到的资源,而不是把节点名写死。

3.3 salloc 分配式:要交互又要资源保障时用

salloc介于两者之间。它先申请资源,资源满足后在提交节点上执行指定命令(默认/bin/sh),你得到一个带合适环境变量的 shell,然后在这个 shell 里用srun跑并行任务。适合需要指定运行节点、又要交互操作的场景。

# 申请 2 个节点、32 个任务,进入交互 shell salloc -N 2 -n 32 -p CPU-Large # 进入 shell 后,用 srun 跑任务 srun ./my_mpi_app # 退出 shell,资源释放 exit

salloc和sbatch的核心区别:salloc在提交作业的节点执行任务,sbatch在分配的第一个节点执行脚本。salloc同样怕终端断开——断开则任务终止。所以它适合「申请资源后手动调试几步」的场景,不适合无人值守的长作业。

注意:三种模式都必须在计算节点跑实际计算,登录节点只用于编译和提交。指南里明确写了「请不要在登录节点直接运行作业(编译除外)」,这是集群礼仪,也是避免影响他人的底线。

4. 作业管理命令:scancel、scontrol 与 sacct 的日常操作

作业提交出去不是就没事了,排队要取消、运行要监控、跑完要查账。这一章把日常管理命令和参数配置讲清楚,都是踩过坑之后固定下来的用法。

4.1 终止与挂起:scancel 和 scontrol hold/release

作业提交错了、参数写大了、不想等了,第一反应是取消。scancel按作业号取消:

# 取消单个作业 scancel 75 # 取消某个作业名的所有作业 scancel --name=my_test # 取消某个队列里自己的所有作业 scancel --partition=CPU-Large --user=$USER

scancel还能发信号给运行中的作业,比如scancel --signal=USR1 75,让程序在收到信号后做清理再退出。这个在需要优雅停止时有用。

排队中的作业如果只是暂时不想跑,不必取消,可以挂起:

# 挂起排队中的作业 scontrol hold 75 # 继续被挂起的作业 scontrol release 75 # 重新运行作业 scontrol requeue 75 # 重新挂起作业 scontrol requeuehold 75 # 把作业提到最优先等待运行 scontrol top 75

scontrol hold只对排队中尚未运行的作业有效,运行中的作业挂起要用scontrol suspend。scontrol requeue会把作业重新放回队列,已运行的部分作废,适合作业跑了一半发现参数错了、想重跑的情况。scontrol top把作业提到自己作业队列的最前面,但不会越过其他用户的高优先级作业。

4.2 查看输出与记账:speek 和 sacct

作业跑起来之后,想看屏幕输出,指南里提到一个speek命令——注意这是指南作者自己写的,不是 Slurm 官方命令,其他系统上不一定有。官方体系里看输出主要靠sbatch脚本里--output指定的文件,或者用sattach吸附到运行中的作业步:

# 吸附到作业步的标准输入输出 sattach 75.0 # 查看记账信息,--format 自定义字段 sacct --format=JobID,JobName,Partition,State,Elapsed,MaxRSS # 查看指定作业的记账信息 sacct -j 75 # 按状态过滤,只看失败的作业 sacct --state=FAILED

sacct查的是记账信息,对应机时费,作业跑完一定要看一眼State和Elapsed。State为COMPLETED是正常结束,FAILED是失败,TIMEOUT是超时被杀,OUT_OF_MEMORY是内存超了。MaxRSS是峰值内存,用来判断下次申请内存该写多少。Elapsed是实际运行时间,用来核对机时消耗。

scontrol show job和sacct的区别:前者看当前状态,后者看历史记账。作业还在队列里或运行中,用scontrol show job;作业已经结束,用sacct。

4.3 文件同步与作业步操作:sbcast 和 sattach

如果作业需要把本地文件分发到各计算节点的/tmp,用sbcast:

# 把本地文件同步到作业分配到的各节点 sbcast -j 75 ./data.bin /tmp/data.bin

sbcast只对本地存储有意义,/home这类共享目录各节点本来就一样,不需要同步。sattach用于吸附到运行中的作业步,监控其 IO,参数-j指定作业号,-s指定作业步号。

提示:sbcast传大文件会占用网络带宽,作业启动阶段传大量数据时,考虑先用共享目录,或者把数据预处理放到作业脚本开头。

5. 避坑与排查:Slurm 提交作业最常见的 5 个坑

这一章是我自己踩过、也见别人踩过的坑,按「现象 → 原因 → 解决」写。每一条都对应一个具体的命令或参数,照着排查基本能定位。

5.1 作业一直 PD,原因显示 Resources

现象:squeue看到作业状态PD,NODELIST(REASON)显示Resources,等很久不动。

原因:目标队列的空闲资源不够,作业在等节点释放。不一定是脚本写错。

解决:先sinfo -p 队列名 -t idle确认队列有没有空闲节点。没有就是真在排队,可以换队列(sinfo看哪个队列 idle 多)或减少申请节点数。如果sinfo显示有 idle 节点但作业还是Resources,检查是不是申请了特定节点(--nodelist)或特定特性(--constraint),导致可选节点被限死。

5.2 作业秒挂,State 显示 FAILED 或 NODE_FAILURE

现象:sbatch提交后几秒作业就结束,sacct看State是FAILED,输出文件里报错。

原因:常见的是脚本里程序路径不对、依赖的 module 没加载、或者srun启动的任务数超过申请的资源。

解决:先看--error指定的出错文件,里面一般有具体报错。检查脚本里module load的模块名是否和集群实际一致,srun的-n是否超过--ntasks。如果是NODE_FAILURE,说明分配到的节点出问题了,scontrol requeue重跑一次通常能换节点。

5.3 申请 GPU 作业但程序看不到 GPU

现象:GPU 作业提交成功,运行中程序报「no CUDA device」。

原因:没有正确申请 GPU 资源,或者申请了但没在脚本里确认环境变量。

解决:脚本里加#SBATCH --gres=gpu:1申请 GPU,运行前echo $CUDA_VISIBLE_DEVICES确认能看到设备号。如果集群用--gpus参数而不是--gres,按集群实际文档写。申请了 GPU 但程序还是看不到,检查是不是在登录节点跑了nvidia-smi而不是在计算节点。

5.4 作业超时被杀,State 显示 TIMEOUT

现象:作业运行到某个时间点被系统杀掉,sacct看State是TIMEOUT。

原因:作业运行时间超过--time设定的墙上时间限制。

解决:sacct --format=Elapsed看实际运行了多久,把--time调大。但注意队列本身有TIMELIMIT上限,sinfo -l能看到,申请超过队列上限的时间会被拒。长作业要么拆成多个短作业,要么换时间限制更宽的队列。

5.5 输出文件为空或找不到

现象:作业显示COMPLETED,但--output指定的文件是空的或不存在。

原因:--output路径写的是相对路径,而作业运行目录和提交目录不一致;或者程序把输出写到了别处。

解决:--output和--error用绝对路径,或者用%j这类占位符让 Slurm 自动命名。作业脚本开头加pwd和ls确认运行目录。如果程序自己重定向了输出,检查程序内部的输出路径配置。

6. 装完怎么验证跑通:一个最小可复现的提交闭环

前面讲了环境、模式、管理、避坑,最后落到「怎么确认这套 Slurm 环境我真的会用」。我的习惯是跑一个最小闭环:从sinfo确认队列,到sbatch提交,到squeue看状态,到sacct查记账,再到输出文件核对结果。五步走完,环境就算验证通过。

先写一个最小测试脚本hello_slurm.sh:

#!/bin/bash #SBATCH --job-name=hello_slurm #SBATCH --partition=CPU-Large #SBATCH --nodes=1 #SBATCH --ntasks-per-node=4 #SBATCH --time=00:05:00 #SBATCH --output=hello_%j.out #SBATCH --error=hello_%j.err echo "Job ID: $SLURM_JOB_ID" echo "Node list: $SLURM_NODELIST" echo "Number of tasks: $SLURM_NTASKS" srun hostname

提交并验证:

# 1. 确认队列可用 sinfo -p CPU-Large # 2. 提交作业 sbatch hello_slurm.sh # 3. 查看作业状态,假设返回作业号 100 squeue -j 100 # 4. 作业结束后查记账 sacct -j 100 --format=JobID,JobName,State,Elapsed,MaxRSS # 5. 核对输出文件 cat hello_100.out

验证时重点看三处:squeue里状态从PD变R再消失,说明调度正常;sacct里State是COMPLETED,说明作业正常结束;输出文件里SLURM_NODELIST和srun hostname的结果一致,说明任务确实在分配到的节点上跑了。如果srun hostname输出的主机名和SLURM_NODELIST对不上,说明任务加载有问题,回去检查srun参数。

再补一个参数对照表,方便提交时快速查:

参数含义常用值
--partition队列名按sinfo实际结果
--nodes节点数1、2、4
--ntasks-per-node每节点任务数等于单节点核数
--time墙上时间限制HH:MM:SS
--output标准输出文件%j.out
--error标准出错文件%j.err
--gres通用资源gpu:1
--mem每节点内存4G、16G

从那以后我每次拿到新集群账号,都强制走一遍这个五步闭环,确认sinfo、sbatch、squeue、sacct、输出文件这条链路通了,再开始跑真实作业。这套流程帮我省下过好几次「脚本写错却以为是集群坏了」的排查时间。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询