博士期间我一直用的是生信技能树的服务器【搭配GPU服务再升级—256线程2Tb内存服务器共享一年仍然是仅需800 】,这个价格非常适合学生党,可以帮助我们低成本快速练习Linux技能,美中不足的是技能树的服务器没有作业调度系统。由于我过去四年没有这方面的使用背景,我完全不适应新单位的集群系统。实际上,大规模以及长期运行的数据需要提交任务至分配节点,如果在登录节点运行较大资源的话,会导致整个服务器卡顿(还可能会被别的用户吐槽,甚至被管理员处罚...)。在这里,我分享一下关于Slurm学习笔记。
Slurm(Simple Linux Utility for Resource Management)是一个常用的作业调度系统,已被全世界的国家超级计算机中心广泛采用,它可以管理计算集群上的资源,并调度和执行作业(例如脚本或分析任务),帮助用户高效地在多个计算节点上运行任务。
Slurm 的基本概念 作业 (Job) : 用户提交给集群去执行的任务,例如运行一个脚本。
节点 (Node) : 集群中的一台计算机,负责执行作业。
登录节点 (Login Node) : 用户通过 SSH 进入集群后最初登录的节点。它用于准备作业、编写脚本和提交作业,但不是作业执行的地方。分配节点 (Allocated Node) : 当你提交作业并成功分配资源时,作业将在这些节点上运行,它们由 Slurm 根据你的资源需求来选择。分区 (Partition) : 一组节点的集合(也可以叫做“队列”),不同分区可能有不同的资源配置或策略。
调度器 (Scheduler) : Slurm 根据资源可用性和作业的优先级,决定作业何时、在哪些节点上执行。
基本工作流程 提交作业 : 用户通过sbatch
命令提交编写好的作业脚本,描述作业的资源需求(如节点数、CPU数、内存等)和执行命令,或者使用 srun
运行交互式作业。
资源分配: Slurm的调度器根据当前的资源可用情况和作业队列中的优先级,分配资源给新提交的作业。
监控作业 : 使用 squeue
查看作业的状态(例如,正在运行或等待中)。
作业输出 : 作业完成后,输出通常会保存在用户指定的文件中。
image-20241018215519860 Slurm 概览 Slurm 功能 sinfo 集群状态 srun 启动交互式作业 squeue 排队作业状态,当前作业状态监控 sbatch 作业/脚本提交 scontrol 查看和修改作业参数 sacct 显示用户的作业历史,默认情况下,sacct显示过去 24小时 的账号作业信息。 scancel 删除作业 sreport 生成使用报告
sinfo
查看集群状态和信息Slurm 功能 sinfo -s 简要格式输出 sinfo -N 查看节点级信息 sinfo -N --states=idle 查看可用节点信息 sinfo --partition=cpu 查看队列信息 sinfo --help 查看所有选项
输出字段 :
STATE : 节点状态:drain
(节点故障), alloc
(节点在用), idle
(节点可用), down
(节点下线), mix
(节点被占用,但仍有剩余资源) 查看总体资源信息:
sinfo#PARTITION AVAIL TIMELIMIT NODES STATE NODELIST #cpu up 7-00:00:0 656 idle cas[001-656] #dgx2 up 7-00:00:0 8 idle vol[01-08]
查看某个特定节点的信息:
sinfo -n
sacct
显示用户作业历史用途 : 查询作业历史记录,显示已完成和正在进行的作业信息,默认情况下,sacct显示过去 24小时 的账号作业信息。
State : 作业状态(COMPLETED、FAILED、CANCELLED等)
squeue
查看作业信息Slurm 功能 squeue -j 查看作业信息 squeue -l 查看细节信息 squeue --nodelist= 查看特定节点作业信息 squeue 查看USER_LIST的作业 squeue --state=R 查看特定状态的作业 squeue --help 查看所有的选项
输出字段 :
ST : 作业状态包括R
(正在运行),PD
(正在排队),CG
(即将完成),CD
(已完成)NODELIST(REASON) : 作业所在节点或排队原因默认情况下,squeue
只会展示在排队或在运行的作业。
$ squeue JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON) 18046 dgx2 ZXLing eenl R 1:35:53 1 vol04 17796 dgx2 python eexdl R 3-00:22:04 1 vol02
显示您自己账户下的作业:
squeue -u JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON) 17923 dgx2 bash hpcwj R 1-12:59:05 1 vol05
-l
选项可以显示更细节的信息。
squeue -u -l JOBID PARTITION NAME USER STATE TIME TIME_LIMI NODES NODELIST(REASON) 17923 dgx2 bash hpcwj RUNNING 1-13:00:53 30-00:00:00 1 vol05
srun
启动交互式作业srun --partition= --nodes= --ntasks= --t= --mem= --c= --pty bash
运行此命令后,你会获得一个交互式的 shell,能够在该节点上直接执行命令。但是srun的缺点是一旦断线就无法重新连接回去,因此推荐使用Linux终端复用神器tmux/screen+srun配合运行,关于tmux,详见我之前写的推文【Tmux:Linux终端复用神器,包好用 】
sbatch
作业提交准备作业脚本然后通过sbatch
提交是 Slurm 的最常见用法。为了将作业脚本提交给作业系统,Slurm 使用
sbatch my_job_script.sh
Slurm 具有丰富的参数集。以下最常用的。
Slurm 含义 -n [count]
总进程数 --ntasks-per-node=[count]
每台节点上的进程数 -p [partition]
作业队列 --job-name=[name]
作业名 --output=[file_name]
标准输出文件 --error=[file_name]
标准错误文件 --time=[dd-hh:mm:ss]
作业最大运行时长 --exclusive
独占节点 --mail-type=[type]
通知类型,可选 all, fail, end,分别对应全通知、故障通知、结束通知 --mail-user=[mail_address]
通知邮箱 --nodelist=[nodes]
偏好的作业节点 --exclude=[nodes]
避免的作业节点 --depend=[state:job_id]
作业依赖 --array=[array_spec]
序列作业
这是一个名为cpu.slurm
的作业脚本,该脚本向cpu队列申请1个节点40核,并在作业完成时通知。在此作业中执行的命令是/bin/hostname
。
#SBATCH --output
标准输出文件:如/share/home/pengchen/work/%x_%A_%a.out#SBATCH --error
ERROR输出文件:如/share/home/pengchen/work/%x_%A_%a.err#SBATCH --partition
工作分区,我们用cpu之类的#SBATCH --nodelist
可以制定在哪个节点运行任务#SBATCH --exclude
可以设置不放在某个节点跑任务#SBATCH --nodes
使用nodes数量#SBATCH --ntasks
tasks数量,可能分配给不同node#SBATCH --ntasks-per-node
每个节点的tasks数量,由于我们只有1 node,所以ntasks和ntasks-per-node是相同的#SBATCH --cpus-per-task
每个task使用的core的数量(默认 1 core per task),同一个task会在同一个node#SBATCH --mem
这个作业要求的内存 (Specified in MB,GB)#SBATCH --mem-per-cpu
每个core要求的内存 (Specified in MB,GB)#!/bin/bash #SBATCH --job-name=hostname #SBATCH --partition=cpu #SBATCH -N 1 #SBATCH --mail-type=end #SBATCH [email protected] #SBATCH --output=%j.out #SBATCH --error=%j.err /bin/hostname
用以下方式提交作业:
sbatch cpu.slurm
squeue
可用于检查作业状态。用户可以在作业执行期间通过SSH登录到计算节点。输出将实时更新到文件[jobid] .out和[jobid] .err。
这里展示一个更复杂的作业要求,其中将启动80个进程,每台主机40个进程。
#!/bin/bash #SBATCH --job-name=LINPACK #SBATCH --partition=cpu #SBATCH -n 80 #SBATCH --ntasks-per-node=40 #SBATCH --mail-type=end #SBATCH [email protected] #SBATCH --output=%j.out #SBATCH --error=%j.err
以下作业请求4张GPU卡,其中1个CPU进程管理1张GPU卡。
#!/bin/bash #SBATCH --job-name=GPU_HPL #SBATCH --partition=dgx2 #SBATCH -n 4 #SBATCH --ntasks-per-node=4 #SBATCH --gres=gpu:4 #SBATCH --mail-type=end #SBATCH [email protected] #SBATCH --output=%j.out #SBATCH --error=%j.err
以下作业启动一个3任务序列(从0到2),每个任务需要1个CPU内核。
#!/bin/bash #SBATCH --job-name=python_array #SBATCH [email protected] #SBATCH --mail-type=ALL #SBATCH --ntasks=1 #SBATCH --time=00:30:00 #SBATCH --array=0-2 #SBATCH --output=python_array_%A_%a.out #SBATCH --output=python_array_%A_%a.err module load miniconda2/4.6.14-gcc-4.8.5source activate YOUR_ENV_NAMEecho "SLURM_JOBID: " $SLURM_JOBID echo "SLURM_ARRAY_TASK_ID: " $SLURM_ARRAY_TASK_ID echo "SLURM_ARRAY_JOB_ID: " $SLURM_ARRAY_JOB_ID python ${SLURM_ARRAY_TASK_ID}.py
在提交到SLURM的作业脚本中,可以激活Conda环境以确保作业在正确的软件环境中运行。以下是一个示例SLURM作业脚本:
#!/bin/bash #SBATCH --job-name=myjob # 作业名称 #SBATCH --output=myjob.out # 标准输出和错误日志 #SBATCH --error=myjob.err # 错误日志文件 #SBATCH --ntasks=1 # 运行的任务数 #SBATCH --time=01:00:00 # 运行时间 #SBATCH --partition=compute # 作业提交的分区 # 加载Conda source ~/miniconda3/etc/profile.d/conda.sh# 激活环境 conda activate myenv# 运行命令 python my_script.py
scancel
取消指定作业Slurm环境变量 Slurm 功能 $SLURM_JOB_ID 作业ID $SLURM_JOB_NAME 作业名 $SLURM_JOB_PARTITION 队列的名称 $SLURM_NTASKS 进程总数 $SLURM_NTASKS_PER_NODE 每个节点请求的任务数 $SLURM_JOB_NUM_NODES 节点数 $SLURM_JOB_NODELIST 节点列表 $SLURM_LOCALID 作业中流程的节点本地任务ID $SLURM_ARRAY_TASK_ID 作业序列中的任务ID $SLURM_SUBMIT_DIR 工作目录 $SLURM_SUBMIT_HOST 提交作业的主机名
参考资料 上交大的超算平台的手册(https://docs.hpc.sjtu.edu.cn/job/slurm.html)