Slurm随手记
写在前面:项目要用,随便记录一下
参考资料:
https://slurm.schedmd.com/quickstart.html
https://blog.csdn.net/weixin_42279314/article/details/109677459
https://hpc.pku.edu.cn/_book/guide/slurm/sbatch.html
简介
Slurm是一个开源、容错、高度可扩展的集群管理和作业调度系统,适用于大型和小型Linux集群。Slurm的操作不需要对内核进行修改,并且相对独立。作为集群工作负载管理器,Slurm具有三个关键功能。首先,它将对资源(计算节点)的独占和/或非独占访问分配给用户一段时间,以便他们可以执行工作。其次,它提供了一个框架,用于在分配的节点集上启动、执行和监视工作(通常是并行作业)。最后,它通过管理挂起的工作队列来仲裁资源争用。
快速开始
框架
Slurm系统由两个关键部分组成,如图1所示。每个计算节点上都有一个slurmd守护进程,而管理节点上则有中央slurmctld守护进程(还可以选择启用故障转移)。slurmd负责提供容错通信。用户可以使用一系列命令来与系统交互,包括:sacct、sacctmgr、salloc、sattach、sbatch、sbcast、scancel、scontrol、scrontab、sdiag、sh5util、sinfo、sprio、squeue、sreport、srun、sshare、sstat、strigger、sview。所有这些命令都可以在集群的任何位置执行。
Slurm系统中有多个组成部分,如图2所示。这些包括节点(计算资源的基本单元)、分区(将节点分组成逻辑集合,可以有重叠)、作业(在指定时间内分配给用户的任务或资源)、以及作业步骤(作业中的一组可能并行执行的任务)。分区可以看作是作业的队列,每个分区都有一些限制,比如作业大小、运行时间、允许使用的用户等。系统会按照优先级将作业分配给分区内的节点,直到该分区的资源(如节点、处理器、内存等)被用尽。一旦作业被分配到一组节点,用户就可以启动并行工作,可以是利用所有节点的单个作业步骤,也可以是几个独立的作业步骤,每个步骤使用分配的一部分资源。
命令
所有Slurm守护进程、命令和API函数都有手册页。命令选项–help还提供了选项的简要摘要。请注意,命令选项都区分大小写。
sacct
用于报告有关活动或已完成作业的作业或作业步骤的会计信息。
salloc
用于实时分配作业的资源。通常用于分配资源并生成一个 shell。然后使用该 shell 执行 srun 命令启动并行任务。
sattach
用于将标准输入、输出和错误以及信号功能附加到当前运行的作业或作业步骤。可以多次附加到和分离从作业。
sbatch
用于提交作业脚本以供以后执行。脚本通常包含一个或多个 srun 命令以启动并行任务。 假设你有一个名为 my_job_script.sh的脚本,其中包含作业的详细信息和要执行的命令。通过以下命令将作业提交到队列:sbatch my_job_script.sh
sbcast
用于将文件从本地磁盘传输到分配给作业的节点的本地磁盘。这可用于有效地使用无磁盘的计算节点或相对于共享文件系统提供更好的性能。
scancel
用于取消挂起或运行中的作业或作业步骤。还可以用于向与运行中的作业或作业步骤关联的所有进程发送任意信号。
scontrol 是用于查看和/或修改 Slurm 状态的管理工具。请注意,许多 scontrol 命令只能以 root 用户身份执行。
sinfo
报告由 Slurm 管理的分区和节点的状态。它具有各种过滤、排序和格式化选项。
sprio
用于显示影响作业优先级的组件的详细视图。
squeue
报告作业或作业步骤的状态。它具有各种过滤、排序和格式化选项。默认情况下,它按优先级顺序报告运行中的作业,然后按优先级顺序报告挂起的作业。
srun
用于实时提交作业以执行或启动实时作业步骤。srun 具有各种选项,可指定资源要求,包括:最小和最大节点数、处理器数、要使用或不使用的特定节点以及作业的节点分配中的特定节点特性(内存、磁盘空间、某些所需功能等)。作业可以包含在作业的节点分配内顺序或并行执行的多个作业步骤。
如果你想直接在命令行中启动一个 MPI 进程,可以使用 srun
,例如srun -n 4 ./my_mpi_program
sshare
显示有关集群上公平份额使用情况的详细信息。请注意,这仅在使用优先级/多因素插件时才可行。
sstat
用于获取有关运行中作业或作业步骤使用的资源的信息。
strigger
用于设置、获取或查看事件触发器。事件触发器包括节点宕机或作业接近其时间限制等情况。
sview
是用于获取和更新由 Slurm 管理的作业、分区和节点状态信息的图形用户界面。
我们可以使用 sinfo
命令来查看系统上存在哪些分区,这些分区包含哪些节点以及系统的整体状态。在下面的例子中,我们发现系统有两个分区:debug 和 batch。分区名字后面的 * 表示 debug 分区是默认的提交作业的分区。我们可以看到两个分区都是 UP 状态,但有些配置可能导致某些分区在非工作时间(例如周末或晚上)处于 DOWN 状态,尤其是用于处理较大作业的分区。关于每个分区的信息可能会跨多行,以清晰地标识节点的不同状态。在这个例子中,两个节点 adev[1-2] 处于下线状态,* 表示这些节点未响应。需要注意的是,节点名称采用 adev 作为通用前缀,后跟数字范围或特定数字的简洁表示方式。这种格式使得对于庞大的集群能够轻松进行管理。sinfo
命令提供了许多选项,可以按照用户的喜好以各种格式查看感兴趣的信息。如需了解更多信息,请参考相关的 man 页面。
adev0: sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
debug* up 30:00 2 down* adev[1-2]
debug* up 30:00 3 idle adev[3-5]
batch up 30:00 3 down* adev[6,13,15]
batch up 30:00 3 alloc adev[7-8,14]
batch up 30:00 4 idle adev[9-12]
接下来,我们使用 squeue
命令确定系统上存在哪些作业。其中,ST 字段表示作业状态。有两个作业处于运行状态(R 是 Running 的缩写),而一个作业处于挂起状态(PD 是 Pending 的缩写)。TIME 字段显示作业运行的时长,格式为天-小时:分钟:秒。NODELIST(REASON) 字段指示作业正在哪里运行,或者它仍然挂起的原因。挂起作业的典型原因包括资源(等待资源可用)和优先级(在优先级较高的作业之后排队)。squeue
命令提供了许多选项,让您可以轻松查看您感兴趣的信息,以您喜欢的格式显示。有关更多信息,请参阅相关的 man 页面。
adev0: squeue
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
65646 batch chem mike R 24:19 2 adev[7-8]
65647 batch bio joan R 0:09 1 adev14
65648 batch math phil PD 0:00 6 (Resources)
scontrol
命令可用于报告有关节点、分区、作业、作业步骤和配置的更详细信息。它还可供系统管理员进行配置更改。以下是一些示例。有关更多信息,请参阅相关的 man 页面。
adev0: scontrol show partition
PartitionName=debug TotalNodes=5 TotalCPUs=40 RootOnly=NO
Default=YES OverSubscribe=FORCE:4 PriorityTier=1 State=UP
MaxTime=00:30:00 Hidden=NO
MinNodes=1 MaxNodes=26 DisableRootJobs=NO AllowGroups=ALL
Nodes=adev[1-5] NodeIndices=0-4
PartitionName=batch TotalNodes=10 TotalCPUs=80 RootOnly=NO
Default=NO OverSubscribe=FORCE:4 PriorityTier=1 State=UP
MaxTime=16:00:00 Hidden=NO
MinNodes=1 MaxNodes=26 DisableRootJobs=NO AllowGroups=ALL
Nodes=adev[6-15] NodeIndices=5-14
adev0: scontrol show node adev1
NodeName=adev1 State=DOWN* CPUs=8 AllocCPUs=0
RealMemory=4000 TmpDisk=0
Sockets=2 Cores=4 Threads=1 Weight=1 Features=intel
Reason=Not responding [slurm@06/02-14:01:24]
65648 batch math phil PD 0:00 6 (Resources)
adev0: scontrol show job
JobId=65672 UserId=phil(5136) GroupId=phil(5136)
Name=math
Priority=4294901603 Partition=batch BatchFlag=1
AllocNode:Sid=adev0:16726 TimeLimit=00:10:00 ExitCode=0:0
StartTime=06/02-15:27:11 EndTime=06/02-15:37:11
JobState=PENDING NodeList=(null) NodeListIndices=
NumCPUs=24 ReqNodes=1 ReqS:C:T=1-65535:1-65535:1-65535
OverSubscribe=1 Contiguous=0 CPUs/task=0 Licenses=(null)
MinCPUs=1 MinSockets=1 MinCores=1 MinThreads=1
MinMemory=0 MinTmpDisk=0 Features=(null)
Dependency=(null) Account=(null) Requeue=1
Reason=None Network=(null)
ReqNodeList=(null) ReqNodeListIndices=
ExcNodeList=(null) ExcNodeListIndices=
SubmitTime=06/02-15:27:11 SuspendTime=None PreSusTime=0
Command=/home/phil/math
WorkDir=/home/phil
上面提供了一些与 Slurm 调度器相关的信息,包括分区、节点和作业的配置。
信息表明系统中存在两个分区(debug 和 batch),其中 debug 是默认分区。adev1 节点当前处于 DOWN* 状态,不响应。还有一个名为 “math” 的作业处于挂起状态(Pending),在 batch 分区中等待资源(Resources)。该作业需求的资源包括 24 个 CPU 核心,要求在 1 个节点上运行,预计运行时间为 10 分钟。
下面是对这些信息的分析:
-
分区信息:
-
debug 分区:
- 节点数量:5
- CPU 总数:40
- 默认分区:是
- 节点范围:adev[1-5]
- 状态:UP
- 最大运行时间:00:30:00
- 可用于非 root 用户的作业:是
-
batch 分区:
- 节点数量:10
- CPU 总数:80
- 默认分区:否
- 节点范围:adev[6-15]
- 状态:UP
- 最大运行时间:16:00:00
- 可用于非 root 用户的作业:是
-
-
节点信息:
- adev1 节点:
- 节点名称:adev1
- 状态:DOWN*
- 可用 CPU 数量:8
- 实际内存:4000 MB
- 临时磁盘:0 MB
- CPU 架构:2 插槽、4 核心、1 线程
- 不响应原因:Not responding [slurm@06/02-14:01:24]
- adev1 节点:
-
作业信息:
- JobID=65648:
- 作业名称:math
- 作业状态:PD(Pending)
- 提交时间:06/02-15:27:11
- 最大运行时间:00:10:00
- 所需 CPU 数量:24
- 所需节点数:1
- 队列:batch
- 预计开始时间:06/02-15:27:11
- 预计结束时间:06/02-15:37:11
- 命令:/home/phil/math
- JobID=65648:
使用 srun
命令可以在单个命令行中创建资源分配并启动作业步骤的任务。根据所使用的 MPI 实现,MPI 作业也可以通过这种方式启动。有关更多 MPI 具体信息,请参阅 MPI 部分。在此示例中,我们在三个节点上执行 /bin/hostname
命令(-N3),并在输出中包含任务编号(-l)。将使用默认分区,默认情况下每个节点将使用一个任务。请注意,srun
命令有许多选项可用于控制分配哪些资源以及如何在这些资源上分配任务。
adev0: srun -N3 -l /bin/hostname
0: adev3
1: adev4
2: adev5
在Python中,你可以使用mpi4py
库来编写MPI程序。下面是一个简单的"Hello, World!"示例,演示了如何在Python中使用MPI:
from mpi4py import MPI
# 初始化MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
# 输出Hello, World!消息,包括进程的排名
print("Hello, World! I am process {} of {}.".format(rank, size))
# 结束MPI
MPI.Finalize()
这个与之前例子的变种在四个任务中执行 /bin/hostname
(-n4)。默认情况下,每个任务将使用一个处理器(请注意,我们没有指定节点数量)。
adev0: srun -n4 -l /bin/hostname
0: adev3
1: adev3
2: adev3
3: adev3
一种常见的操作模式是提交一个脚本以供以后执行。在这个例子中,脚本的名称是 my.script,我们明确使用节点 adev9 和 adev10(-w “adev[9-10]”,请注意使用了节点范围表达式)。我们还明确说明后续的作业步骤将每个生成四个任务,这将确保我们的分配至少包含四个处理器(每个任务启动一个处理器)。输出将显示在文件 my.stdout 中(“-o my.stdout”)。这个脚本包含了嵌入其中的作业的时间限制。其他选项可以通过在脚本中的任何要执行的命令之前使用 “#SBATCH” 前缀,后跟选项来提供。在命令行上提供的选项将覆盖在脚本中指定的任何选项。请注意,my.script 包含了在分配的第一个节点上执行的命令 /bin/hostname,以及使用 srun 命令启动并按顺序执行的两个作业步骤。
adev0: cat my.script
#!/bin/sh
#SBATCH --time=1
/bin/hostname
srun -l /bin/hostname
srun -l /bin/pwd
adev0: sbatch -n4 -w "adev[9-10]" -o my.stdout my.script
sbatch: Submitted batch job 469
adev0: cat my.stdout
adev9
0: adev9
1: adev9
2: adev10
3: adev10
0: /home/jette
1: /home/jette
2: /home/jette
3: /home/jette
上面这个例子展示了一个使用 Slurm 的脚本来执行作业的过程:
-
脚本内容 (my.script):
#!/bin/sh #SBATCH --time=1 /bin/hostname srun -l /bin/hostname srun -l /bin/pwd
#SBATCH --time=1
脚本指定了作业的执行时间为 1 分钟。- 首先执行
/bin/hostname
命令,输出当前主机的主机名。 -l
选项是srun
的一个参数,它指示srun
在每个计算节点上运行作业。这意味着每个节点都会运行相同的作业。- 接着使用
srun -l /bin/hostname
启动了四个任务,每个任务执行/bin/hostname
命令,并输出每个任务的编号及对应的主机名。 - 最后使用
srun -l /bin/pwd
启动了四个任务,每个任务执行/bin/pwd
命令,输出每个任务的编号及对应的当前工作目录。
-
提交作业 (sbatch):
adev0: sbatch -n4 -w "adev[9-10]" -o my.stdout my.script sbatch: Submitted batch job 469
- 使用
sbatch
提交了作业,指定了四个任务(-n4
),使用节点范围表达式指定了节点adev9
和adev10
(-w "adev[9-10]"
),并将输出重定向到 my.stdout 文件(-o my.stdout
)。
- 使用
-
查看输出 (my.stdout):
adev9 0: adev9 1: adev9 2: adev10 3: adev10 0: /home/jette 1: /home/jette 2: /home/jette 3: /home/jette
- 输出显示了作业执行的结果。首先,显示了执行
/bin/hostname
的任务,然后是执行/bin/pwd
的任务。每个任务都有相应的任务编号,以及执行命令的结果。
- 输出显示了作业执行的结果。首先,显示了执行
总体而言,这个例子演示了如何通过 Slurm 在指定的节点上执行作业,包括如何在作业中运行不同的命令,并将输出保存到文件。
最终的操作模式是创建资源分配并在该分配中启动作业步骤。salloc
命令用于创建资源分配,并通常在该分配中启动一个 shell。通常会使用 srun
命令在该分配中执行一个或多个作业步骤,以启动任务(根据使用的 MPI 类型,启动机制可能会有所不同,详见下面的 MPI 详细信息)。最后,使用 exit
命令终止由 salloc
创建的 shell。Slurm 不会自动将可执行文件或数据文件迁移到分配给作业的节点。文件必须存在于本地磁盘或某个全局文件系统中(例如 NFS 或 Lustre)。我们提供了 sbcast
工具,使用 Slurm 的分层通信将文件传输到已分配节点的本地存储中。在此示例中,我们使用 sbcast
将可执行程序 a.out
传输到已分配节点的本地存储中的 /tmp/joe.a.out
。执行程序后,我们从本地存储中删除它。
tux0: salloc -N1024 bash
$ sbcast a.out /tmp/joe.a.out
Granted job allocation 471
$ srun /tmp/joe.a.out
Result is 3.14159
$ srun rm /tmp/joe.a.out
$ exit
salloc: Relinquishing job allocation 471
salloc -N1024 bash
:该命令用于分配1024个节点并启动一个交互式bash会话。这意味着用户将在Slurm集群上获得1024个计算节点的进程,可以在这些节点上运行命令。
sbcast
是Slurm命令之一,用于将文件广播到集群的所有节点。
srun /tmp/joe.a.out
:该命令使用srun
命令在集群节点上运行/tmp/joe.a.out
可执行文件。srun
是Slurm命令之一,用于在集群节点上运行作业。
srun rm /tmp/joe.a.out
:该命令使用srun
命令在集群节点上删除/tmp/joe.a.out
文件。
exit
:该命令退出当前的bash会话。
salloc: Relinquishing job allocation 471
:这条消息表示Slurm调度系统释放了作业分配号为471的作业。
建议
考虑将相关工作放入一个包含多个作业步骤的单个 Slurm 作业中,这样做既有助于提高性能,又便于管理。每个 Slurm 作业可以包含大量的作业步骤,而 Slurm 在管理作业步骤的开销远低于单独作业的开销。
作业数组是管理具有相同资源需求的一组批处理作业的有效机制。大多数 Slurm 命令都可以将作业数组视为单个实体来管理,可以作为单独的元素(任务)或作为单个实体(例如,在单个命令中删除整个作业数组)。
MPI
MPI的使用取决于所使用的MPI类型。有三种基本不同的操作模式由这些不同的MPI实现使用:
- Slurm直接启动任务并通过PMI2或PMIx API执行通信初始化。(由大多数现代MPI实现支持。)
- Slurm为作业创建资源分配,然后mpirun使用Slurm的基础设施启动任务(较旧版本的OpenMPI)。
- Slurm为作业创建资源分配,然后mpirun使用除Slurm之外的某种机制启动任务,例如SSH或RSH。这些任务在Slurm的监控或控制之外启动。在放弃作业分配时,建议配置Slurm的epilog以清理这些任务。强烈建议使用pam_slurm_adopt。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!