一、Slurm常规运行操作
在HPC上运行任务的主要方法是通过sbatch命令提交一个脚本。例如:
sabtch MyJobScript.sh
在MyJobScript.sh中的命令会在第一个被找到的、可用的、满足资源要求的compute node上进行运算,sbatch会在提交任务后立刻返回一个信息。提交的命令不会作为前台进程运行,并且也不会在断开HPC连接之后停止运行。
编写SBATCH脚本通常来说,一个sbatch脚本分为3个部分:#!/bin/bash 这一行使得脚本可以作为一个bash script运行;以#SBATCH开头的行理论上是bash命令,但是它们实际上设置了SLURM调度程序的各种参数;要运行的命令。注意,我们应当把所有的#SBATCH开头的行放在一起,同时放在脚本的顶部。必须在所有的#SBATCH行结束之后才能写bash code和变量设置。
一个典型的任务提交脚本如下所示:
'''
#!/bin/bash
#SBATCH -n 1 # 指定核心数量
#SBATCH -N 1 # 指定node的数量
#SBATCH -t 0-5:00 # 运行总时间,天数-小时数-分钟, D-HH:MM
#SBATCH -p debug # 提交到哪一个分区
#SBATCH --mem=2000 # 所有核心可以使用的内存池大小,MB为单位
#SBATCH -o myjob.o # 把输出结果STDOUT保存在哪一个文件
#SBATCH -e myjob.e # 把报错结果STDERR保存在哪一个文件
#SBATCH --mail-type=ALL # 发送哪一种email通知:BEGIN,END,FAIL,ALL
#SBATCH --mail-user=netid@nyu.edu # 把通知发送到哪一个邮箱
#SBATCH --constraint=2630v3 # the Features of the nodes, using command " showcluster " could find them.
#SBATCH --gres=gpu:n # 需要使用多少GPU,n是需要的数量
runYourCommandHere
SLURM系统会将许多环境变量(包括PATH和当前工作目录)从当前会话复制到运行脚本的计算主机。因此,您在指定文件位置的时候,可以只指定改文件相对于当前位置的位置(例如./project/myfiles/myfile.txt)。
[补充:要注意,对于Python多处理作业,您需要指定-c 16,而不是{},因为后者可能会在不同的节点(服务器)上分配作业,multiprocessing模块无法处理这些任务,而前者将确保所有保留的核心都在同一节点上。]
#SBATCH -n 1 or --ntasks=1
这一行指定了你需要的核心数量。只有在你使用的程序本身能够使用多核运行的时候,你才应该请求多个核心。如果这个参数省略不写,那么SLURM会假设你只请求一个核心。
一些科学计算工具是支持多进程运行的。但是也有一些是不支持的,例如常规的R脚本都是不支持多线程的。
#SBATCH -N 1 or --nodes=1
这一行设置了你需要的node数量。如果说你使用了MPI,并且在一个node上需要多个核心,你应当计算清楚具体需要多少node和核心。
#SBATCH -t 0-5:00 or --time=05:00:00
这一行说明了任务的最大运行时间(单位是分钟)。如果你的任务事实上需要的运行时间大于你设定的值,那么你的任务会在到达最大运行时间时被终止。如果这个参数省略不写,那么你的任务会被安排30分钟的最大运行时间。
#SBATCH -p serial or --partition=serial
这一行指定了你的脚本会在哪个SLURM partition运行。Partition是SLURM使用的关于队列的术语,是在使用SLURM中的一系列资源和参数的集合。
#SBATCH --mem=2000
在使用HPC cluster的时候,应当指定需要的内存数量(以MB为单位),这样可以让系统上的各个工作以最大的效率运行。
这是在发起资源申请的时候最重要的参数。如果你申请的内存量小于你的程序需要的量,那么程序会在运行途中crash。如果你申请的内存量远大于你的程序需要的量,那么本可以用于其他任务的资源就被浪费了。此外,每个人都有一个“fairshare”值用于计划工作优先级,如果你总是超额很多请求资源,你的工作优先级会下降。
我们可以通过两个参数指定需要的内存大小,第一个是--mem,第二个是--mem-per-cpu。第一种方式--mem可以指定整个一个或者多个核心可用的整个内存池的大小,是被推荐使用的方式。当我们需要做跨多节点的计算任务时,我们必须使用第二种方式--mem-per-cpu,因为这种方式可以指定好分配给每一个核心具体内存大小。
--mem和--mem-per-cpu在运行多核任务时有很大区别(对于单核作业,两者是等效的)。 --mem设置所有内核的总内存,而--mem-per-cpu设置了内核的内存。 如果使用--mem请求两个内核(-n 2)和4 Gb内存,那么每个内核将有2 GB RAM。 如果使用--mem-per-cpu指定4 Gb,则每个内核有4 GB RAM,总计8 GB。
如果我们省略这个参数不写,那么我们会得到最小的分配大小,通常是2000MB。如果我们的程序在运行中超过了我们申请的内存大小,那么任务会被结束。
#SBATCH -o myjob.o or --output=myjob.o
这行命令指定了标准输出standard out会被添加到哪个文件里面。如果我们指定的是一个相对路径,那么文件会被保存在当前的工作目录下。如果这个参数被省略了,那么所有的输出都会被储存在当前工作目录的一个名为slurm-JOBID.out的文件里面。
#SBATCH -e myjob.e or --error=myjob.e
这行命令指定了标准错误信息standard error会被添加到哪个文件里面,此外SLURM提交和处理时的错误也会被保存在这个文件。如果这个参数被省略了,那么所有的输出都会被储存在当前工作目录的一个名为slurm-JOBID.out的文件里面。
#SBATCH --mail-type=ALL
因为我们的任务是在后台被处理的,因此当任务完成以后(--mail-type=END)发送一封邮件给我们有利于我们知道任务的处理进度。,我们也可以选择在其他处理阶段发送邮件,例如开始START、失败FAIL、和所有阶段(ALL)。
#SBATCH --mail-user=yourName@nyu.edu
指定了将--mail-type信息发送到哪一个邮箱地址。
#SBATCH --constraint=2630v3
这一行指定了将任务提交到feature是2630v3的nodes。
#SBATCH --gres=gpu:n
当我们需要使用GPU进行计算的时候,需要加上这一行。n的值就是需要的GPU数量。如果在运行中不需要用到GPU,那么不要写这一行。
我们通常使用squeue和sacct来监控在SLURM中的作业活动。squeue是最重要、最准确的监控工具,因为它可以直接查询SLURM控制器。sacct也可以报告之前完成的任务,但是因为它是通过查询SLURM database获取信息,因此有时候sacct查到的信息和squeue查到的信息会有一点区别。
运行在不附带arguments的情况下运行squeue会显示所有当前正在运行的任务。当使用 squeue -u yourUserName的时候,会只显示你提交的任务。
squeue -u yourUserName
或者是查询一个特定任务:
squeue -j JobID
如果在squeue最后加上了-l选项(意思是long output),那么系统还会返回任务的运行状态。
我们可以通过saact查询特定任务的细节:
sacct -j JobID
但是,由于sacct可以访问到很多SLURM使用的resource accounting fields,它可以比squeue提供更加详细信息。例如,如果要查看用户Michael今日使用的内存资源:
sacct -u michael
使用-j参数查询到的工作状态有等待PENDING、运行中RUNNING、已完成COMPLETED、已取消CANCELLED、失败FAILED:
取消任务的方法是输入scancel加上任务的ID:
scancel JobID
我们可以通过squeue -u命令查询到我们需要的任务的ID。
尽管使用批量提交的方式,通常是充分运用HPC的计算资源的方法,但是前台的交互式任务也是可以运行的。通常我们建议在如下情况使用前台的交互式任务:
在运行交互式任务的时候要注意,我们要指定的partition是interactpartition。
此外在交互式任务中,我们需要用srun,而不是sbatch来初始化。例如,我们要在交互式队列中启动一个命令行shell(/bin/bash),申请500MB内存、6小时运行时间、1个核心、1个node,那么可以输入下面的命令:
srun -p serial --pty --mem 500 -t 0-06:00 /bin/bash
当交互式的session启动以后,你会发现你不在login node里面了,而是位于专门用于此队列的计算节点之一。
--pty命令使得这个session可以像标准的终端一样运行。
在必要的时候,你也可以直接运行一个程序。不过我们不鼓励这样做,因为这会导致在设置环境变量的时候出现问题。在导入一个MATLAB的模块之后,你可以用下面的命令启动这个程序:
srun -p serial --pty --mem=4000 -t 0-06:00 matlab
或者是:
salloc –p serial --mem=4000 --time=02:00:00
srun yourCommand1
srun yourCommand2
srun yourCommand3
…
exit
有两个文件夹可以用来储存,一个是HOME文件夹,位于/gpfsnyu/home,这个文件夹每天会被备份两次,并且会把快照保存一个月;另一个是SCRATCH文件夹,位于/gpfsnyu/scratch,这个文件夹不会被备份,可以放一些乱七八糟的数据文件。
/scratch
/scratch文件系统适合处理大块的输入输出,例如顺序读取和写入大文件。但是,单个的输入输出操作成本相对较高,所以频繁执行小的输入输出的程序将给元数据服务(metadata service)带来很重的负担,在极端情况下甚至会造成系统的不稳定。系统管理员通常会探测到这种频繁的输入输出,并且可能会结束这个任务。
/scratch最适合处理低频的、大的读取和写入,因此,建议用户在这个文件夹处理大文件,而不是数量很多的小文件。如果真的要在执行任务的时候频繁地访问临时文件,应当使用compute node的本地磁盘,甚至是compute node上的RAM文件系统来减少/scratch文件系统的输入输出操作。
通常来说文件系统很难处理把大量的文件放在一个目录的情况,这会儿导致处理这个文件夹的时候会非常的慢,同时也会影响其他用户的使用。一个文件夹中的文件数量应当小于1000个,如果有跟多的文件的时候,应当新建立几个文件夹、分开装。
在/scratch目录下,所有的HPC账户拥有5TB的磁盘空间,但是这个目录中的数据是不进行系统备份的,因此由文件丢失、系统崩溃、硬件损坏造成的数据丢失以后是无法恢复的,因此用户要自己留意备份重要的数据。
由于/scratch文件夹中超过60天没有被使用的文件将被移除,因此不建议把源代码、脚本、库、可执行文件等数据放在这个文件夹,这些重要的文件应该放在/home文件夹下面。此外,也不建议把/scratch中的文件夹软链接到/home文件夹里面。
单一系统映像
Slurm是一个开源,容错,高度可扩展的集群管理和作业调度系统,适用于大型和小型Linux集群。Slurm不需要对其操作进行内核修改,并且相对独立。作为集群工作负载管理器,Slurm有三个关键功能。首先,它在一段时间内为用户分配对资源(计算节点)的独占和/或非独占访问,以便他们可以执行工作。其次,它提供了一个框架,用于在分配的节点集上启动,执行和监视工作(通常是并行作业)。最后,它通过管理待处理工作的队列来仲裁资源争用。
(1)主控服务slurmctld
故障切换 资源监控 队列管理 作业调度
(2)记账存储服务slurmdbd
记账数据 配置信息 故障切换
(3)数据库MySQL
记账和配置信息存储
(4)计算代理slurmd
启动任务 监控任务 分层通信
(5)认证服务munge
内部通信认证
扩展性(功能/规模)高性能(提交/调度)灵活性(自定义插件)容错性(服务/节点/作业
资源绑定(CPU、MEM、类GPU加速卡等各类资源)关联调度(如类GPU加速卡关联CPU)
能耗管理(限频、开关机、记账等)拓扑调度(基于拓扑结构调度,限定交换机数等)
基础功能完善
优先级策略(Multi-Factor)
作业调度(FairShare/Backfill/ FCFS, etc)
资源竞争(Exclusive/Preempt/Gang, etc)
多级限制(Cluster/Account/User/Partition, etc)
资源预留(CPU/MEM/类GPU加速卡/License等)
兼容性/交互性良好
MPI兼容(IntelMPI/MVAPICH/OpenMPI,etc)
LSF兼容(bsub/bjobs/bqueue/bhosts, etc)
PBS兼容(qsub/qstat/pbsnodes/pestat, etc)
分析工具(融合Influxdb/ES/HDF5等,方便分析)
对于批处理作业(提交后立即返回该命令行终端,用户可进行其它操作)使用sbatch命令提交作业脚本,作业被调度运行后,在所分配的首个节点上执行作业脚本。在作业脚本中也可使用srun命令加载作业任务。提交时采用的命令行终端终止,也不影响作业运行。
资源分配与任务加载两步均通过srun命令进行:当在登录shell中执行srun命令时,srun首先向系统提交作业请求并等待资源分配,然后在所分配的节点上加载作业任务。采用该模式,用户在该终端需等待任务结束才能继续其它操作,在作业结束前,如果提交时的命令行终端断开,则任务终止。一般用于短时间小作业测试。
分配作业模式类似于交互式作业模式和批处理作业模式的融合。用户需指定所需要的资源条件,向资源管理器提出作业的资源分配请求。提交后,作业处于排队,当用户请求资源被满足时,将在用户提交作业的节点上执行用户所指定的命令,指定的命令执行结束后,运行结束,用户申请的资源被释放。在作业结束前,如果提交时的命令行终端断开,则任务终止。典型用途是分配资源并启动一个shell,然后在这个shell中利用srun运行并行作业。
(1)salloc后面如果没有跟定相应的脚本或可执行文件,则默认选择/bin/sh,用户获得了一个合适环境变量的shell环境。
(2)salloc和sbatch最主要的区别是salloc命令资源请求被满足时,直接在提交作业的节点执行相应任务,而sbatch则当资源请求被满足时,在分配的第一个节点上执行相应任务。
(3)salloc在分配资源后,再执行相应的任务,很适合需要指定运行节点和其它资源限制,并有特定命令的作业。
(1)查看分区——sinfo
(2)查询排队和运行状态的作业——squeue
(3)删除作业命令——scancel
(4)控制作业命令——scontrol