数据科学工厂 发表于 2024-6-17 10:15:06

集群作业提交系统:slurm

## 导读

本文将介绍 `slurm`,一个 `Linux`服务器中的集群管理和作业调度系统。并对其基础命令和运行方式进行实战演练。

## 1. 简介

!(https://swindler-typora.oss-cn-chengdu.aliyuncs.com/typora_imgs/image-20221009224312631.png)

(https://slurm.schedmd.com/overview.html "slurm") ((https://bioinformaticsworkbook.org/Appendix/Unix/01_slurm-basics.html "Docs"):Simple Linux Utility for Resource Management)是一个开源、容错和高度可扩展的集群管理和作业调度系统,适用于大型和小型 ` Linux` 集群。`Slurm` 的运行不需要内核修改,并且相对独立。作为集群工作负载管理器,`Slurm` 具有三个关键功能。首先,它在一段时间内为用户分配对资源(计算节点)的独占和/或非独占访问权限,以便他们可以执行工作。其次,它为在分配的节点集上启动、执行和监控工作(通常是并行工作)提供了一个框架。最后,它通过管理待处理工作队列来仲裁资源的争用。

## 2. 目标

!(https://swindler-typora.oss-cn-chengdu.aliyuncs.com/typora_imgs/image-20221009225607568.png)

1. 让用户请求计算节点进行分析(作业)
2. 提供一个框架(命令)来启动、取消和监控作业
3. 跟踪所有作业,以确保每个人都可以有效地使用所有计算资源,而不会互相干扰。

## 3. 命令

| command| Description                        |
| :------- | :----------------------------------- |
| sbatch   | 向 SLURM 提交批处理脚本            |
| squeue   | 列出当前正在运行或在队列中的所有作业 |
| scancel| 取消提交的工作                     |
| sinfo    | 检查所有分区中节点的可用性         |
| scontrol | 查看特定节点的配置或有关作业的信息   |
| sacct    | 显示所有作业的数据                   |
| salloc   | 预留交互节点                         |

### 3.1. squeue

第一个 `SLURM `命令是 `squeue`。它可以显示所有使用超级计算机的人提交给 `SLURM` 调度程序的所有作业的列表。此命令可以告诉您超级计算资源的繁忙程度以及您的作业是否正在运行。

!(https://swindler-typora.oss-cn-chengdu.aliyuncs.com/typora_imgs/image-20221005233424932.png)

- 结果解读

| Header column    | Definition                           |
| :--------------- | :------------------------------------- |
| JOBID            | 该作业的ID,通常是一个很大的数字       |
| PARTITION      | 分配给给定作业的分区                   |
| NAME             | 用户为此作业提供给 SLURM 的名称      |
| USER             | 提交作业的用户名                     |
| ST               | 作业状态,running(R), PenDing(PD)      |
| NODES            | 请求的节点数                           |
| NODELIST(REASON) | 作业在哪个节点上运行(或未运行的原因) |

- 根据用户名查看任务运行情况

```sh
squeue -u $USER# 用户名
```

!(https://swindler-typora.oss-cn-chengdu.aliyuncs.com/typora_imgs/image-20221005233731476.png)

### 3.2. scancel

如果您提交作业并意识到由于某种原因需要取消它,您将在 `squeue` 中使用带有上述 JOBID 的 `scancel` 命令

```sh
scancel 2867457
```

这会向 `SLURM` 调度发送信号以停止正在运行的作业或从 ` SLURM` 队列中删除待处理的作业。

### 3.3. sbatch

`sbatch` 命令是最重要的命令,用于向超级计算集群提交作业。作业是在计算资源上运行的脚本。该脚本包含您要在超级计算节点上运行的命令。

```sh
sbatch slurm.batch.sh
```

一旦您编写了 `SLURM `提交脚本,就超级容易使用。这是许多新用户卡住的部分,但它确实还不错。您只需将标题添加到其中包含您的命令的文本文件。

### 3.4. sinfo

有时可能很难获得一个节点并且您最终在 `SLURM` 队列中很长一段时间,或者您只是想在提交之前测试一个脚本并离开以确保它运行良好。找出可用节点的最简单方法是使用 `sinfo` 命令。

```sh
$ sinfo
PARTITION      AVAILTIMELIMITNODESSTATE NODELIST
debug               up    1:00:00      1maint ceres19-compute-26
debug               up    1:00:00      1    mix ceres14-compute-4
debug               up    1:00:00      1   idle ceres19-compute-25
brief-low         up    2:00:00      2maint ceres19-compute-
brief-low         up    2:00:00      1down* ceres19-compute-37
brief-low         up    2:00:00   59    mix ceres18-compute-,ceres19-compute-
brief-low         up    2:00:00      4alloc ceres18-compute-18,ceres19-compute-
brief-low         up    2:00:00   26   idle ceres19-compute-
mem768-low          up    2:00:00      3   idle ceres18-mem768-0,ceres19-mem768-
mem-low             up    2:00:00      3    mix ceres18-mem-,ceres19-mem-1
```

`SINFO`提供以下信息

| Header column | Definition                           |
| :------------ | :----------------------------------- |
| PARTITION   | 一组节点                           |
| AVAIL         | 节点是否启动、关闭或处于其他状态   |
| TIMELIMIT   | 用户可以请求给定分区中的节点的时间量 |
| NODES         | 给定分区中的节点数                   |
| STATE         | 维护、混合、空闲、停机、分配         |
| NODELIST      | 具有给定状态的节点名称               |

使用此信息,可以找到具有可用于作业的空闲节点的分区。不幸的是, `sinfo` 本身有点混乱,所以我创建了一个别名,将输出格式化为更易于阅读

```sh
sinfo -o "%20P %5D %14F %10m %11l %N"
PARTITION            NODES NODES(A/I/O/T) MEMORY   TIMELIMIT   NODELIST
debug                3   0/3/0/3      126000+    1:00:00   ceres14-compute-4,ceres19-compute-
brief-low            92    33/58/1/92   381000   2:00:00   ceres18-compute-,ceres19-compute-
priority-gpu         1   1/0/0/1      379000   14-00:00:00 ceres18-gpu-0
short*               100   51/48/1/100    126000+    2-00:00:00ceres14-compute-,ceres18-compute-,ceres19-compute-
medium               67    49/17/1/67   126000+    7-00:00:00ceres14-compute-,ceres18-compute-,ceres19-compute-
long               34    31/3/0/34      126000+    21-00:00:00 ceres14-compute-,ceres18-compute-,ceres19-compute-
mem                  8   3/4/1/8      1530000+   7-00:00:00ceres14-mem-,ceres18-mem-2,ceres19-mem-
mem768               1   0/1/0/1      763000   7-00:00:00ceres18-mem768-1
huge               1   1/0/0/1      4:16:1   3095104    14990      1-00:00:00fat,AVX,AVX2,AVX novahuge001
```

### 3.5. scontrol

如果您需要查看特定节点的配置以确定该类型的节点是否足以进行分析或诊断问题(如内存分段不足故障)。 `scontrol` 可用于查找节点上的信息,例如 ceres14-compute-8

```sh
$ scontrol show nodes ceres14-compute-8

NodeName=ceres14-compute-8 Arch=x86_64 CoresPerSocket=10
   CPUAlloc=0 CPUTot=40 CPULoad=0.01
   AvailableFeatures=AVX
   ActiveFeatures=AVX
   Gres=(null)
   NodeAddr=ceres14-compute-8 NodeHostName=ceres14-compute-8 Version=19.05.5
   OS=Linux 3.10.0-1062.12.1.el7.x86_64 #1 SMP Tue Feb 4 23:02:59 UTC 2020
   RealMemory=126000 AllocMem=0 FreeMem=85536 Sockets=2 Boards=1
   State=IDLE ThreadsPerCore=2 TmpDisk=975 Weight=1 Owner=N/A MCS_label=N/A
   Partitions=short,geneious
   BootTime=2020-02-17T17:14:55 SlurmdStartTime=2020-02-18T17:12:06
   CfgTRES=cpu=40,mem=126000M,billing=40
   AllocTRES=
   CapWatts=n/a
   CurrentWatts=0 AveWatts=0
   ExtSensorsJoules=n/s ExtSensorsWatts=0 ExtSensorsTemp=n/s
```

有时,您想了解更多关于您刚刚运行或当前运行的作业的信息。

```sh
scontrol show job 2909617

JobId=2909617 JobName=bash
   UserId=remkv6(298590) GroupId=domain users(101) MCS_label=N/A
   Priority=84730 Nice=0 Account=gif QOS=gif
   JobState=RUNNING Reason=None Dependency=(null)
   Requeue=1 Restarts=0 BatchFlag=0 Reboot=0 ExitCode=0:0
   RunTime=06:58:38 TimeLimit=10:00:00 TimeMin=N/A
   SubmitTime=2020-05-18T07:29:05 EligibleTime=2020-05-18T07:29:05
   AccrueTime=Unknown
   StartTime=2020-05-18T07:29:05 EndTime=2020-05-18T17:29:05 Deadline=N/A
   SuspendTime=None SecsPreSuspend=0 LastSchedEval=2020-05-18T07:29:05
   Partition=long_1node192 AllocNode:Sid=nova:71501
   ReqNodeList=(null) ExcNodeList=(null)
   NodeList=nova027
   BatchHost=nova027
   NumNodes=1 NumCPUs=4 NumTasks=4 CPUs/Task=1 ReqB:S:C:T=0:0:*:*
   TRES=cpu=4,mem=20400M,node=1
   Socks/Node=* NtasksPerN:B:S:C=4:0:*:* CoreSpec=*
   MinCPUsNode=4 MinMemoryCPU=5100M MinTmpDiskNode=0
   Features=(null) DelayBoot=00:00:00
   OverSubscribe=OK Contiguous=0 Licenses=(null) Network=(null)
   Command=bash
   WorkDir=/work/gif/remkv6/Baum/04_DovetailSCNGenome/01_mikadoRerurn/01_BrakerFix/braker
   Comment=Time 600, Med priority, overdrawn
   Power=
```

提示如果您将下面代码放在 SLURM 脚本的末尾,它将在您的工作完成后将其输出到您的标准输出文件。

```sh
scontrol show job $SLURM_JOB_ID
```

### 3.6. sacct

此命令提供有关已提交作业的有用信息。

| Column         | Description                               |
| :------------- | :---------------------------------------- |
| JobID          | 作业编号                                  |
| JobName      | 任务名称                                  |
| Partition      | 它正在运行或排队等待 SLURM 队列的哪个分区 |
| Account      | 它在哪个帐户/组上运行                     |
| AllocCPUS      | 分配/请求的 CPU 数量                      |
| State ExitCode | 工作状态或退出代码                        |

该命令本身只会为您提供有关您的工作的信息

```sh
sacct

# 添加 -a 参数将提供有关所有帐户的信息。
sacct -a

# 下面的命令可以提供更多有用的列信息。
sacct -a --format JobID,Partition,Timelimit,Start,Elapsed,NodeList%20,ExitCode,ReqMem,MaxRSS,MaxVMSize,AllocCPUS

```

### 3.7. salloc

也可以通过首先使用 `salloc` 在分区中保留一个节点来交互地运行作业脚本中的命令

```sh
# 下面的命令将在短分区中为 1 个节点提供 4 个 cpu,时间为 00 小时:30 分钟:00 秒

$ salloc -N 1 -n 4 -p short -t 00:30:00

salloc: Pending job allocation 2935626
salloc: job 2935626 queued and waiting for resources
salloc: job 2935626 has been allocated resources
salloc: Granted job allocation 2935626
salloc: Waiting for resource configuration
salloc: Nodes ceres14-compute-48 are ready for job
export TMPDIR=/local/bgfs//2935626
export TMOUT=5400
```

## 4. Scripts

`SLURM` 脚本包含一个带有 ` SLURM SBATCH` 注释 #SBATCH 的标题。这些注释告诉 `SLURM` 以下信息。

- 节点数
- 所需的处理器或作业数量
- 要使用的分区/队列类型(可选)
- 内存要求(可选)
- 想要运行作业的时间长度(每个分区都有一个默认值)
- 在哪里写入输出和错误文件
- 在 HPC 上运行时的作业名称
- 获取工作状态的电子邮件 ID(可选)

这是最常用的#SBATCH 注释的表格说明

| SBATCH command                      | Description                                                      |
| :---------------------------------- | :----------------------------------------------------------------- |
| #SBATCH -N 1                        | 预留单个节点                                                       |
| #SBATCH -n 4                        | 作业步骤将启动最多 4 个作业                                        |
| #SBATCH -p short                  | 预留在短分区                                                       |
| #SBATCH -t 01:00:00               | 预留 01 时:00 分:00 秒                                             |
| #SBATCH -J sleep                  | 工作的名称是“睡眠”                                             |
| #SBATCH -o sleep.o%j                | 将任何 std 输出写入名为 sleep.o%j 的文件,其中 %j 自动替换为 jobid |
| #SBATCH -e sleep.e%j                | 将任何 std 输出写入名为 sleep.e%j 的文件,其中 %j 自动替换为 jobid |
| #SBATCH –mail-user=user@domain.edu | 通过此电子邮件地址通知我                                           |
| #SBATCH –mail-type=begin         | 工作开始时通过电子邮件通知                                       |
| #SBATCH –mail-type=end             | 工作结束时通过电子邮件通知                                       |

## 5. script

现在您对#SBATCH 注释有了更多了解,`SLURM` 作业脚本可以直接编写,包含两个组件:

- 带有#SBATCH 注释的 SLURM 标头定义了您需要的资源
- 您要运行的命令

### 5.1. header

一旦你编写了这个,你可以通过根据你的需要修改#SBATCH 注释来将它重用于你需要的其他脚本。

```bash
#!/bin/bash

# 下面以单个 `#SBATCH` 开头的所有行都是 SLURM SBATCH 注释

#SBATCH -N 1
#SBATCH -n 4
#SBATCH -p short
#SBATCH -t 01:00:00
#SBATCH -J sleep
#SBATCH -o sleep.o%j
#SBATCH -e sleep.e%j
#SBATCH --mail-user=user@domain.edu
#SBATCH --mail-type=begin
#SBATCH --mail-type=end

cd $SLURM_SUBMIT_DIR # 此行将您更改为作业开始后提交脚本的目录
```

### 5.2. 命令

```bash
## 以下几行是要运行的命令

sleep 10 && echo "I slept for 10 seconds"

scontrol show job $SLURM_JOB_ID
## scontrol 是一个 slurm 命令,用于查看 slurm 配置或状态。查看您使用了多少资源。
```

### 5.3. 提交

```sh
sbatch slurm.batch.sh# 提交命令
```

作业完成后会出现以下文件

```sh
sleep.o2935316 # 这是标准输出,其中 2935316 是 JOBID
sleep.e2935316 # 这是标准错误,其中 2935316 是 JOBID
```
页: [1]
查看完整版本: 集群作业提交系统:slurm