

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Slurm 多队列模式指南
<a name="multiple-queue-mode-slurm-user-guide"></a>

AWS ParallelCluster 版本 2.9.0 为 Slurm Workload Manager () Slurm 引入了多队列模式和新的扩展架构。

以下各节概述了如何使用具有新引入扩展架构的 Slurm 集群。

## 概述
<a name="multiple-queue-mode-slurm-user-guide-overview"></a>

新的扩展架构基于 Slurm 的[云调度指南](https://slurm.schedmd.com/elastic_computing.html)和节能插件。有关节能插件的更多信息，请参阅 [Slurm Power Saving Guide](https://slurm.schedmd.com/power_save.html)。在新架构中，可能可供集群使用的资源通常在 Slurm 配置中预定义为云节点。

## 云节点生命周期
<a name="multiple-queue-mode-slurm-user-guide-cloud-node-lifecycle"></a>

在整个生命周期中，云节点会进入以下几种（如果不是全部）状态：`POWER_SAVING`、`POWER_UP` (`pow_up`)、`ALLOCATED` (`alloc`) 和 `POWER_DOWN` (`pow_dn`)。在某些情况下，云节点可能会进入 `OFFLINE` 状态。下面的列表详细介绍了云节点生命周期中这些状态的几个方面。
+ 处于 `POWER_SAVING` 状态的节点在 `sinfo` 中显示 `~` 后缀（例如 `idle~`） 在这种状态下，没有支持该节点的 EC2 实例。但 Slurm 仍然可以向该节点分配作业。
+ 正在过渡到 `POWER_UP` 状态的节点将在 `sinfo` 中显示 `#` 后缀（例如 `idle#`）。
+ 当 Slurm 向处于 `POWER_SAVING` 状态的节点分配作业时，该节点会自动转变为 `POWER_UP` 状态。除此以外，还可以使用 `scontrol update nodename=nodename state=power_up` 命令手动将节点置于 `POWER_UP` 状态。在此阶段，将调用 `ResumeProgram`，启动 EC2 实例并将其配置为支持 `POWER_UP` 节点。
+ 当前可供使用的节点在 `sinfo` 中不显示任何后缀（例如 `idle`）。节点设置完毕并加入集群后，即可用于运行作业。在此阶段，节点已正确配置并可供使用。一般而言，我们建议 EC2 中的实例数量与可用节点的数量相同。在大多数情况下，在创建集群后静态节点始终可用。
+ 正在过渡到 `POWER_DOWN` 状态的节点在 `sinfo` 中显示 `%` 后缀（例如 `idle%`）。经过 [`scaledown_idletime`](scaling-section.md#scaledown-idletime) 之后，动态节点会自动进入 `POWER_DOWN` 状态。相比之下，静态节点在大多数情况下不会关闭。但可以使用 `scontrol update nodename=nodename state=powering_down` 命令手动将节点置于 `POWER_DOWN` 状态。在此状态下，与节点关联的实例将会终止，节点将重置回 `POWER_SAVING` 状态以便在经过 [`scaledown_idletime`](scaling-section.md#scaledown-idletime) 之后供将来使用。`scaledown-idletime` 设置作为 `SuspendTimeout` 设置保存到 Slurm 配置中。
+ 离线的节点将在 `sinfo` 中显示 `*` 后缀（例如 `down*`）。如果 Slurm 控制器无法联系某个节点，或者静态节点被禁用并且支持实例被终止，则该节点将会离线。

现在考虑以下 `sinfo` 示例中所示的节点状态。

```
$ sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
efa          up   infinite      4  idle~ efa-dy-c5n18xlarge-[1-4]
efa          up   infinite      1   idle efa-st-c5n18xlarge-1
gpu          up   infinite      1  idle% gpu-dy-g38xlarge-1
gpu          up   infinite      9  idle~ gpu-dy-g38xlarge-[2-10]
ondemand     up   infinite      2   mix# ondemand-dy-c52xlarge-[1-2]
ondemand     up   infinite     18  idle~ ondemand-dy-c52xlarge-[3-10],ondemand-dy-t2xlarge-[1-10]
spot*        up   infinite     13  idle~ spot-dy-c5xlarge-[1-10],spot-dy-t2large-[1-3]
spot*        up   infinite      2   idle spot-st-t2large-[1-2]
```

`spot-st-t2large-[1-2]` 和 `efa-st-c5n18xlarge-1` 节点已经设置了支持实例，并且可供使用。`ondemand-dy-c52xlarge-[1-2]` 节点处于 `POWER_UP` 状态，应会在几分钟内可用。`gpu-dy-g38xlarge-1` 节点处于 `POWER_DOWN` 状态，它将在 [`scaledown_idletime`](scaling-section.md#scaledown-idletime)（默认为 120 秒）之后过渡到 `POWER_SAVING` 状态。

所有其他节点都处于 `POWER_SAVING` 状态，没有支持它们的 EC2 实例。

## 使用可用节点
<a name="multiple-queue-mode-slurm-user-guide-working-with-available-nodes"></a>

可用节点由 EC2 实例提供支持。默认情况下，可以使用节点名称直接通过 SSH 加入到实例中（例如 `ssh efa-st-c5n18xlarge-1`）。可以使用 `scontrol show nodes nodename` 命令并检查 `NodeAddr` 字段来检索实例的私有 IP 地址。对于不可用的节点，`NodeAddr` 字段不应指向正在运行的 EC2 实例，而是应与节点名称相同。

## 作业状态和提交
<a name="multiple-queue-mode-slurm-user-guide-job-states"></a>

在大多数情况下，提交的作业会立即分配给系统中的节点，或者如果所有节点都已分配，则将其置于待处理状态。

如果为作业分配的节点包括任何处于 `POWER_SAVING` 状态的节点，则该作业将以 `CF` 或 `CONFIGURING` 状态开始。此时，该作业将会等待处于 `POWER_SAVING` 状态的节点过渡到 `POWER_UP` 状态并变为可用。

为作业分配的所有节点都可用后，该作业将进入 `RUNNING` (`R`) 状态。

默认情况下，所有作业都提交到默认队列（在 Slurm 中称为分区）。此队列由队列名称后面的后缀 `*` 表示。您可以使用 `-p` 作业提交选项选择队列。

所有节点都配置了以下特征，这些特征可以在作业提交命令中使用：
+ 实例类型（例如 `c5.xlarge`）。
+ 节点类型（`dynamic` 或 `static`。）

通过使用 `scontrol show nodes nodename` 命令并查看 `AvailableFeatures` 列表，您可以查看特定节点的所有可用特征。

另一个考虑因素是作业。首先考虑集群的初始状态，可以通过运行 `sinfo` 命令来查看该状态。

```
$ sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
efa          up   infinite      4  idle~ efa-dy-c5n18xlarge-[1-4]
efa          up   infinite      1   idle efa-st-c5n18xlarge-1
gpu          up   infinite     10  idle~ gpu-dy-g38xlarge-[1-10]
ondemand     up   infinite     20  idle~ ondemand-dy-c52xlarge-[1-10],ondemand-dy-t2xlarge-[1-10]
spot*        up   infinite     13  idle~ spot-dy-c5xlarge-[1-10],spot-dy-t2large-[1-3]
spot*        up   infinite      2   idle spot-st-t2large-[1-2]
```

请注意，`spot` 是默认队列。它由 `*` 后缀表示。

向默认队列 (`spot`) 的一个静态节点提交作业。

```
$ sbatch --wrap "sleep 300" -N 1 -C static
```

向 `EFA` 队列的一个动态节点提交作业。

```
$ sbatch --wrap "sleep 300" -p efa -C dynamic
```

向 `ondemand` 队列的八 (8) 个 `c5.2xlarge` 节点和两 (2) 个 `t2.xlarge` 节点提交作业。

```
$ sbatch --wrap "sleep 300" -p ondemand -N 10 -C "[c5.2xlarge*8&t2.xlarge*2]"
```

向 `gpu` 队列的一个 GPU 节点提交作业。

```
$ sbatch --wrap "sleep 300" -p gpu -G 1
```

现在考虑使用 `squeue` 命令的作业状态。

```
$ squeue
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                12  ondemand     wrap   ubuntu CF       0:36     10 ondemand-dy-c52xlarge-[1-8],ondemand-dy-t2xlarge-[1-2]
                13       gpu     wrap   ubuntu CF       0:05      1 gpu-dy-g38xlarge-1
                 7      spot     wrap   ubuntu  R       2:48      1 spot-st-t2large-1
                 8       efa     wrap   ubuntu  R       0:39      1 efa-dy-c5n18xlarge-1
```

作业 7 和 8（在 `spot` 和 `efa` 队列中）已经在运行 (`R`)。作业 12 和 13 仍在配置 (`CF`)，可能正在等待实例变为可用。

```
# Nodes states corresponds to state of running jobs
$ sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
efa          up   infinite      3  idle~ efa-dy-c5n18xlarge-[2-4]
efa          up   infinite      1    mix efa-dy-c5n18xlarge-1
efa          up   infinite      1   idle efa-st-c5n18xlarge-1
gpu          up   infinite      1   mix~ gpu-dy-g38xlarge-1
gpu          up   infinite      9  idle~ gpu-dy-g38xlarge-[2-10]
ondemand     up   infinite     10   mix# ondemand-dy-c52xlarge-[1-8],ondemand-dy-t2xlarge-[1-2]
ondemand     up   infinite     10  idle~ ondemand-dy-c52xlarge-[9-10],ondemand-dy-t2xlarge-[3-10]
spot*        up   infinite     13  idle~ spot-dy-c5xlarge-[1-10],spot-dy-t2large-[1-3]
spot*        up   infinite      1    mix spot-st-t2large-1
spot*        up   infinite      1   idle spot-st-t2large-2
```

## 节点状态和特征
<a name="multiple-queue-mode-slurm-user-guide-node-state-features"></a>

在大多数情况下，节点状态完全由 AWS ParallelCluster 根据本主题前面所述的云节点生命周期中的特定流程进行管理。

但是， AWS ParallelCluster 还会替换或终止处于不健康`DRAINED`状态的节点`DOWN`和具有不健康后备实例的节点。有关更多信息，请参阅 [`clustermgtd`](processes.md#clustermgtd)。

## 分区状态
<a name="multiple-queue-mode-slurm-user-guide-partition-states"></a>

AWS ParallelCluster 支持以下分区状态。Slurm 分区就是 AWS ParallelCluster中的队列。
+ `UP`：表示该分区处于活动状态。这是分区的默认状态。在此状态下，该分区中的所有节点都处于活动状态并且可供使用。
+ `INACTIVE`：表示该分区处于非活动状态。在此状态下，将会终止支持非活动分区的节点的所有实例。不会为非活动分区中的节点启动新实例。

## pcluster 启动和停止
<a name="multiple-queue-mode-slurm-user-guide-pcluster-start-stop"></a>

运行[`pcluster stop`](pcluster.stop.md)时，所有分区都将置于`INACTIVE`状态，并且 AWS ParallelCluster 进程会将分区保持在`INACTIVE`状态。

运行 [`pcluster start`](pcluster.start.md) 时，所有分区最初都处于 `UP` 状态。但是， AWS ParallelCluster 进程不会使分区保持`UP`状态。您需要手动更改分区状态。所有静态节点将在几分钟后变为可用。请注意，将分区设置为 `UP` 不会增加任何动态容量。如果 [`initial_count`](compute-resource-section.md#compute-resource-initial-count) 大于 [`max_count`](compute-resource-section.md#compute-resource-max-count)，则在分区状态更改为 `UP` 状态时，可能无法满足 [`initial_count`](compute-resource-section.md#compute-resource-initial-count)。

当 [`pcluster start`](pcluster.start.md) 和 [`pcluster stop`](pcluster.stop.md) 正在运行时，您可以通过运行 [`pcluster status`](pcluster.status.md) 命令并检查 `ComputeFleetStatus` 来查看集群的状态。下面列出了可能的状态：
+ `STOP_REQUESTED`：[`pcluster stop`](pcluster.stop.md) 请求已发送到集群。
+ `STOPPING`：`pcluster` 进程当前正在停止集群。
+ `STOPPED`：`pcluster` 进程已完成停止进程，所有分区都处于 `INACTIVE` 状态，并且所有计算实例都已终止。
+ `START_REQUESTED`：[`pcluster start`](pcluster.start.md) 请求已发送到集群。
+ `STARTING`：`pcluster` 进程当前正在启动集群
+ `RUNNING`：`pcluster` 进程已完成启动过程，所有分区都处于 `UP` 状态，静态节点将在几分钟后可用。

## 手动控制队列
<a name="multiple-queue-mode-slurm-user-guide-manual-control-queue"></a>

在某些情况下，您可能需要对集群中的节点或队列（在 Slurm 中称为分区）进行一些手动控制。您可以通过以下常用过程管理集群中的节点。
+ 启动处于 `POWER_SAVING` 状态的动态节点：运行 `scontrol update nodename=nodename state=power_up` 命令或提交占位符 `sleep 1` 作业，请求一定数量的节点，然后依靠 Slurm 来启动所需数量的节点。
+ 之前关闭动态节点的电源[`scaledown_idletime`](scaling-section.md#scaledown-idletime)：`DOWN`使用`scontrol update nodename=nodename state=down`命令将动态节点设置为。 AWS ParallelCluster 自动终止并重置已关闭的动态节点。通常，我们不建议直接使用 `scontrol update nodename=nodename state=power_down` 命令将节点设置为 `POWER_DOWN`。这是因为 AWS ParallelCluster 会自动处理关闭过程，无需手动干预。因此，我们建议您尽可能将节点设置为 `DOWN`。
+ 禁用队列（分区）或停止特定分区中的所有静态节点：使用 `scontrol update partition=queue name state=inactive` 命令将特定队列设置为 `INACTIVE`。此操作会终止支持该分区中节点的所有实例。
+ 启用队列（分区）：使用 `scontrol update partition=queue name state=up` 命令将特定队列设置为 `INACTIVE`。

## 扩展行为和调整
<a name="multiple-queue-mode-slurm-user-guide-scaling-behavior"></a>

下面是正常扩展工作流程的示例：
+ 调度器收到需要两个节点的作业。
+ 调度器将两个节点转换为 `POWER_UP` 状态，并使用节点名称（例如 `queue1-dy-c5xlarge-[1-2]`）调用 `ResumeProgram`。
+ `ResumeProgram` 启动两个 EC2 实例并分配 `queue1-dy-c5xlarge-[1-2]` 的私有 IP 地址和主机名，等待 `ResumeTimeout`（默认时段为 60 分钟（1 小时）），然后重置节点。
+ 实例配置完成并加入集群。作业开始在实例上运行。
+ 作业完成。
+ 经过配置的 `SuspendTime`（设置为 [`scaledown_idletime`](scaling-section.md#scaledown-idletime)）后，调度器将实例置于 `POWER_SAVING` 状态。调度器将 `queue1-dy-c5xlarge-[1-2]` 置于 `POWER_DOWN` 状态并使用节点名称调用 `SuspendProgram`。
+ 为两个节点调用 `SuspendProgram`。节点保持在 `POWER_DOWN` 状态，例如通过保持 `idle%` 状态持续 `SuspendTimeout`（默认时段为 120 秒（2 分钟））。在 `clustermgtd` 检测到节点正在关闭后，它会终止支持实例。然后，它将 `queue1-dy-c5xlarge-[1-2]` 配置为空闲状态并重置私有 IP 地址和主机名，使它们能够启动以供将来的作业使用。

现在，如果出现问题，特定节点的某个实例由于某种原因无法启动，则会发生以下情况。
+ 调度器收到需要两个节点的作业。
+ 调度器将两个云爆发节点置于 `POWER_UP` 状态并使用节点名称（例如 `queue1-dy-c5xlarge-[1-2]`）调用 `ResumeProgram`。
+ `ResumeProgram` 仅启动一 (1) 个 EC2 实例并配置 `queue1-dy-c5xlarge-1`，但未能为 `queue1-dy-c5xlarge-2` 启动实例。
+ `queue1-dy-c5xlarge-1` 将不受影响，并将在进入 `POWER_UP` 状态后上线。
+ `queue1-dy-c5xlarge-2` 处于 `POWER_DOWN` 状态，由于 Slurm 检测到节点故障，因此会对作业自动重新排队。
+ 经过 `SuspendTimeout`（默认为 120 秒（2 分钟））之后 `queue1-dy-c5xlarge-2` 变为可用。在此期间，作业将重新排队，并可以开始在另一个节点上运行。
+ 上述过程将会重复，直到作业可以在可用节点上运行而不发生故障。

有两个定时参数可以根据需要进行调整。
+ `ResumeTimeout`（默认为 60 分钟（1 小时））：`ResumeTimeout` 控制 Slurm 将节点置于关闭状态之前等待的时间。
  + 如果你的 pre/post 安装过程需要将近那么长的时间，那么延长这个时间可能会很有用。
  + 这也是在出现问题时 AWS ParallelCluster 在更换或重置节点之前等待的最长时间。如果在启动或设置过程中发生任何错误，则计算节点会自行终止。接下来，当 AWS ParallelCluster 进程检测到实例已终止时，它还会替换该节点。
+ `SuspendTimeout`（默认为 120 秒（2 分钟））：`SuspendTimeout` 控制将节点放回系统并准备好再次使用的速率。
  + `SuspendTimeout` 越短，节点重置就会越快，并且 Slurm 能够更频繁地尝试启动实例。
  + `SuspendTimeout` 越长，故障节点的重置就会越慢。在此期间，Slurm 会尝试使用其他节点。如果 `SuspendTimeout` 超过几分钟，则 Slurm 将会循环尝试系统中的所有节点。对于大型系统（超过 1000 个节点），较长的 `SuspendTimeout` 可能有利于减轻 Slurm 上因频繁对失败作业重新排队而产生的压力。
  + 请注意，`SuspendTimeout`这并不是指 AWS ParallelCluster 等待终止节点的后备实例的时间。`power down` 节点的支持实例将会立即终止。终止过程通常在几分钟内完成。但在此期间，节点仍处于关闭状态，无法在调度器中使用。

## 新架构的日志
<a name="multiple-queue-mode-slurm-user-guide-logs"></a>

以下列表包含多队列架构的关键日志。与 Amazon Logs 一起使用的 CloudWatch 日志流名称的格式*logIdentifier*为`{hostname}.{instance_id}.{logIdentifier}`，后面是日志名称。有关更多信息，请参阅 [与 Amazon CloudWatch 日志集成](cloudwatch-logs.md)。
+ `ResumeProgram`:

  `/var/log/parallelcluster/slurm_resume.log` (`slurm_resume`)
+ `SuspendProgram`:

  `/var/log/parallelcluster/slurm_suspend.log` (`slurm_suspend`)
+ `clustermgtd`:

  `/var/log/parallelcluster/clustermgtd.log` (`clustermgtd`)
+ `computemgtd`:

  `/var/log/parallelcluster/computemgtd.log` (`computemgtd`)
+ `slurmctld`:

  `/var/log/slurmctld.log` (`slurmctld`)
+ `slurmd`:

  `/var/log/slurmd.log` (`slurmd`)

## 常见问题以及调试方法：
<a name="multiple-queue-mode-slurm-user-guide-common-issues"></a>

**无法启动、加电或加入集群的节点：**
+ 动态节点：
  + 检查 `ResumeProgram` 日志，查看是否对该节点调用过 `ResumeProgram`。如果没有，请检查 `slurmctld` 日志以确定 Slurm 是否尝试过对该节点调用 `ResumeProgram`。请注意，`ResumeProgram` 上不正确的权限可能会导致它静默失败。
  + 如果调用了 `ResumeProgram`，请查看是否为该节点启动了实例。如果无法启动实例，则应有明确的错误消息，说明实例启动失败的原因。
  + 如果启动了实例，则可能在引导过程中出现了问题。从`ResumeProgram`日志中找到相应的私有 IP 地址和实例 ID，然后在 Logs 中查看特定实例的相应引导 CloudWatch 日志。
+ 静态节点：
  + 检查 `clustermgtd` 日志，查看是否为该节点启动了实例。如果没有，则应有明确的错误说明实例启动失败的原因。
  + 如果启动了实例，则在引导过程中出现了问题。从`clustermgtd`日志中找到相应的私有 IP 和实例 ID，然后在 Logs 中查看特定实例的相应引导 CloudWatch 日志。

**节点意外替换或终止、节点故障**
+ 节点 replaced/terminated 出乎意料
  + 在大多数情况下，`clustermgtd` 会处理所有节点维护操作。要检查 `clustermgtd` 是否替换或终止了节点，请查看 `clustermgtd` 日志。
  + 如果 `clustermgtd` 替换或终止了节点，则应显示一条消息，说明该操作的原因。如果原因与调度器有关（例如，节点处于 `DOWN` 状态），请查看 `slurmctld` 日志以获取更多详细信息。如果原因与 EC2 有关，请使用工具检查该实例的状态或日志。例如，您可以检查该实例是否有已安排的事件或失败的 EC2 运行状况检查。
  + 如果 `clustermgtd` 没有终止该节点，请检查 `computemgtd` 是否终止了该节点，或者 EC2 是否终止了该实例以回收竞价型实例。
+ 节点故障
  + 在大多数情况下，如果节点出现故障，作业会自动重新排队。在 `slurmctld` 日志中查看作业或节点失败的原因，并在其中分析具体情况。

**替换或终止实例时出现故障、关闭节点时出现故障**
+ 通常，`clustermgtd` 会处理所有预期的实例终止操作。在 `clustermgtd` 日志中查看其无法替换或终止节点的原因。
+ 对于 [`scaledown_idletime`](scaling-section.md#scaledown-idletime) 失败的动态节点，请在 `SuspendProgram` 日志中查看 `slurmctld` 运行的程序是否以特定节点作为参数。请注意，`SuspendProgram` 实际上并不执行任何特定的操作，它只是记录被调用时的时间。所有实例终止和 `NodeAddr` 重置均由 `clustermgtd` 完成。Slurm 会在 `SuspendTimeout` 后将节点置于 `IDLE` 状态。

**其它问题**
+ AWS ParallelCluster 不会做出工作分配或扩大规模的决策。它只是尝试按照 Slurm 的指示启动、终止和维护资源。

  对于与作业分配、节点分配和扩展决策有关的问题，请查看 `slurmctld` 日志中是否存在错误。