常见问题解答

管理者相关

研究人员相关

用户相关

设计作业

提交作业

调度

被终止的作业

管理作业

资源限制

管理员相关

测试环境

构建和安装

集群管理

计费数据库

计算节点 (slurmd)

用户管理

作业

常规故障排除

错误消息

第三方集成

管理者相关

Slurm 真的是免费的吗?
是的,Slurm 是免费的开源软件:

  • Slurm 是根据 自由软件基金会 的定义免费提供的。
  • Slurm 的 源代码文档 在 GNU GPL v2 下公开提供。
  • Slurm 可以 下载、使用、修改和再分发,而无需支付任何费用。

我为什么要使用 Slurm 或其他免费软件?
免费软件与专有软件的质量差异很大,但这种机制已被证明能够生产出高质量的软件,受到全球公司的信任。Linux 内核就是一个突出的例子,通常被信任用于网络服务器、基础设施服务器、超级计算机和移动设备。

同样,自 2002 年首次发布以来,Slurm 已成为超级计算领域的可信工具,并在 2010 年成立 SchedMD 以继续开发 Slurm。如今,Slurm 驱动着大多数 TOP500 超级计算机。通常从商业工作负载管理器切换到 Slurm 的客户报告更高的可扩展性、更好的性能和更低的成本。

我为什么要为免费软件付费?
免费软件并不意味着没有成本。编写、测试、分发和维护软件需要大量的时间和专业知识。如果软件庞大而复杂,例如 Slurm 或 Linux 内核,这些成本可能会变得非常可观。

Slurm 通常用于全球主要计算集群中的重要任务。由于可用的广泛功能和提供这些功能所需的代码复杂性,许多组织更愿意有专家提供量身定制的建议和故障排除帮助。虽然 Slurm 拥有一个全球开发社区,融入了前沿技术,但 SchedMD 的人员开发了大部分代码,并可以提供具有竞争力的商业支持和现场培训。

"Slurm" 代表什么?
没有。

最初,"SLURM"(完全大写)是 "简单 Linux 资源管理工具" 的缩写。在 2012 年,首选的大小写更改为 Slurm,并且缩写被丢弃——开发人员更愿意认为 Slurm 是 "复杂的",而不是 "简单的"。随着 Slurm 继续扩展其调度能力,"资源管理" 标签也被视为过时。

研究人员相关

我应该如何引用涉及 Slurm 的工作?
我们建议引用 JSSPP 2023 的同行评审论文: Slurm 工作负载管理器的架构。

Jette, M.A., Wickberg, T. (2023). Slurm 工作负载管理器的架构。
在:Klusáček, D., Corbalán, J., Rodrigo, G.P. (编辑) 并行处理的作业调度策略。JSSPP 2023。计算机科学讲义,
第 14283 卷。施普林格,查姆。https://doi.org/10.1007/978-3-031-43943-8_1

用户相关

设计作业

我如何在单个脚本中运行多个作业?
Slurm 作业只是资源分配。您可以在该分配中执行许多作业步骤,无论是并行还是顺序。有些作业实际上以这种方式启动数千个作业步骤。作业步骤将被分配未被其他作业步骤占用的节点。这本质上在作业内部为作业步骤提供了第二级资源管理。

我如何在现有作业分配中运行作业?
有一个 srun 选项 --jobid 可用于指定作业的 ID。 对于批处理作业或在现有资源分配中,环境变量 SLURM_JOB_ID 已经被定义, 因此所有作业步骤将在该作业分配中运行,除非另有指定。 唯一的例外是在提交批处理作业时。 当从现有批处理作业中提交批处理作业时,它被视为新的作业分配请求,并将获得新的作业 ID,除非明确使用 --jobid 选项设置。 如果您指定批处理作业应使用现有分配,则该作业分配将在该批处理作业终止时释放。

Slurm 文档提到 CPU、核心和线程。什么被认为是 CPU?
如果您的节点配置了超线程,则 CPU 相当于一个超线程。 否则,CPU 相当于一个核心。 您可以使用命令 "scontrol show node" 来确定您的节点是否每个核心有多个线程,并查看 "ThreadsPerCore" 的值。

请注意,即使在启用超线程的系统上,资源通常会在核心级别分配给作业(见下面的注意事项)。 两个不同的作业不会共享一个核心,除非通过使用分区的 OverSubscribe 配置参数。 例如,在 ThreadsPerCore=2 的节点上请求三个任务的作业将被分配两个完整的核心。 请注意,Slurm 命令包含许多选项,以控制与基础板、插槽、核心和线程有关的资源分配。

(注意: 例外情况是,如果系统管理员配置了 SelectTypeParameters=CR_CPU,并且每个节点的 CPU 数量没有其插槽/核心/线程的说明。在这种情况下,每个线程将被独立调度为 CPU。这不是典型配置。)

我如何在我的分配中在特定节点上运行特定任务?
srun 的一种分配方法 '-m--distribution' 是 'arbitrary'。这意味着您可以告诉 Slurm 以您想要的任何方式布局您的任务。例如,如果我有一个 2 个节点的分配,并希望在第一个节点上运行 4 个任务,在第二个节点上运行 1 个任务,而我的节点从 SLURM_JOB_NODELIST 中分配为 tux[0-1],我的 srun 行将如下所示:

srun -n5 -m arbitrary -w tux[0,0,0,0,1] hostname

如果我想要类似的东西,但希望第三个任务在 tux 1 上,我可以运行:

srun -n5 -m arbitrary -w tux[0,0,1,0,0] hostname

这里有一个简单的 Perl 脚本,名为 arbitrary.pl,可以轻松地在 SLURM_JOB_NODELIST 中的节点上布局任务。

#!/usr/bin/perl
my @tasks = split(',', $ARGV[0]);
my @nodes = `scontrol show hostnames $SLURM_JOB_NODELIST`;
my $node_cnt = $#nodes + 1;
my $task_cnt = $#tasks + 1;

if ($node_cnt < $task_cnt) {
  print STDERR "错误:您只有 $node_cnt 个节点,但请求在 $task_cnt 个节点上布局。\n";
  $task_cnt = $node_cnt;
}

my $cnt = 0;
my $layout;
foreach my $task (@tasks) {
  my $node = $nodes[$cnt];
  last if !$node;
  chomp($node);
  for(my $i=0; $i < $task; $i++) {
    $layout .= "," if $layout;
    $layout .= "$node";
  }
  $cnt++;
}
print $layout;

我们现在可以在我们的 srun 行中以这种方式使用此脚本。

srun -m arbitrary -n5 -w `arbitrary.pl 4,1` -l hostname

这将在分配的第一个节点上布局 4 个任务,在第二个节点上布局 1 个任务。

我如何在批处理作业的输出或错误文件名中获取任务 ID?
如果您希望按任务分开输出,您需要构建一个包含此规范的脚本。例如:

$ cat test
#!/bin/sh
echo begin_test
srun -o out_%j_%t hostname

$ sbatch -n7 -o out_%j test
sbatch: 提交批处理作业 65541

$ ls -l out*
-rw-rw-r--  1 jette jette 11 Jun 15 09:15 out_65541
-rw-rw-r--  1 jette jette  6 Jun 15 09:15 out_65541_0
-rw-rw-r--  1 jette jette  6 Jun 15 09:15 out_65541_1
-rw-rw-r--  1 jette jette  6 Jun 15 09:15 out_65541_2
-rw-rw-r--  1 jette jette  6 Jun 15 09:15 out_65541_3
-rw-rw-r--  1 jette jette  6 Jun 15 09:15 out_65541_4
-rw-rw-r--  1 jette jette  6 Jun 15 09:15 out_65541_5
-rw-rw-r--  1 jette jette  6 Jun 15 09:15 out_65541_6

$ cat out_65541
begin_test

$ cat out_65541_2
tdev2

Slurm 如何为我的作业建立环境?
Slurm 进程不是在 shell 下运行,而是由 slurmd 守护进程直接执行(假设使用 srun 启动进程)。 在执行 srun 命令时生效的环境变量会传播到生成的进程中。 ~/.profile~/.bashrc 脚本不会在进程启动时执行。您还可以查看 srun 和 sbatch 的 --export 选项。有关详细信息,请参见手册页。

make 命令可以利用分配给 Slurm 作业的资源吗?
是的。GNU make 版本 3.81 的补丁可作为 Slurm 分发的一部分,位于文件 contribs/make-3.81.slurm.patch 中。对于 GNU make 版本 4.0,您可以使用文件 contribs/make-4.0.slurm.patch 中的补丁。 此补丁将使用 Slurm 在作业当前的资源分配中启动任务。根据要编译的模块的大小,这可能会提高或降低性能。如果大多数模块有数千行,使用额外资源应该会弥补 Slurm 启动任务的开销。在现有 Slurm 分配中使用 make 的 -j 选项。 在 Slurm 分配之外,make 的行为将保持不变。

我如何使用 Slurm 运行 Ansys 程序?
如果您是指 Ansys 应用程序的交互式运行,则可以使用此简单脚本(适用于 Ansys Fluent):

$ cat ./fluent-srun.sh
#!/usr/bin/env bash
HOSTSFILE=.hostlist-job$SLURM_JOB_ID
if [ "$SLURM_PROCID" == "0" ]; then
    srun hostname -f > $HOSTSFILE
    fluent -t $SLURM_NTASKS -cnf=$HOSTSFILE -ssh 3d
    rm -f $HOSTSFILE
fi
exit 0

要运行交互式会话,请使用 srun,如下所示:

$ srun -n <tasks> ./fluent-srun.sh

提交作业

为什么我的 srun 选项被忽略?
在命令 srun 之后的所有内容都会被检查,以确定它是否是 srun 的有效选项。第一个 不是 srun 有效选项的标记被视为要执行的命令,之后的所有内容被视为该命令的选项。例如:

srun -N2 uptime -pdebug

srun 将 "-N2" 作为其自身的选项处理。"uptime" 是要执行的命令,而 "-pdebug" 被视为 uptime 命令的选项。根据提供的命令和选项,如果选项有效,您可能会收到无效选项消息或意外行为。

srun 的选项应出现在要运行的命令之前:

srun -N2 -pdebug uptime

为什么 srun --overcommit 选项不允许多个作业在节点上运行?
--overcommit 选项是指示作业或作业步骤愿意在作业分配中每个处理器上执行多个任务的一种方式。例如, 考虑一个有两个处理器节点的集群。srun 执行行可能是这样的

srun --ntasks=4 --nodes=1 a.out

这将导致分配两个节点,以便每个四个任务都分配一个处理器。请注意,srun --nodes 选项指定 最小节点数,并可选地指定最大节点数。命令行

srun --ntasks=4 --nodes=1-1 a.out

将导致请求被拒绝。如果将 --overcommit 选项添加到任一命令行,则将仅为所有 四个任务分配一个节点。

可以通过使用 srun 的 --oversubscribe 选项结合 Slurm 的分区配置中的 OverSubscribe 参数,在同一计算资源(例如 CPU)上同时执行多个作业。有关更多信息,请参见 srun 和 slurm.conf 的手册页。

为什么 srun --u/--unbuffered 选项会在我的输出中添加回车符?
许多程序使用的 libc 库内部缓冲输出,而不是立即写入。这是出于性能原因。 禁用这种内部缓冲的唯一方法是将程序配置为写入伪终端 (PTY) 而不是常规文件。 此配置会导致 某些 libc 实现在所有换行符之前添加回车符。 在某些情况下,删除回车符将导致所需的格式,而在其他情况下则会导致格式错误。 无论如何,Slurm 并没有添加回车符,而是显示实际程序的输出。

sbatch 和 srun 命令有什么区别?
srun 命令有两种不同的操作模式。首先,如果不在现有作业中运行(即不在由 salloc 或 sbatch 创建的 Slurm 作业分配中),则它将创建一个作业分配并启动一个应用程序。 如果在现有分配中运行,srun 命令仅启动应用程序。 对于这个问题,我们将仅讨论第一种操作模式,并比较使用 sbatch 和 srun 命令创建作业分配。

srun 命令旨在用于交互式使用,有人监控输出。 应用程序的输出被视为 srun 命令的输出,通常在用户的终端上。 sbatch 命令旨在提交脚本以供稍后执行,其输出写入文件。 在作业分配中使用的命令选项几乎是相同的。 最明显的选项差异是 sbatch 命令支持 作业数组 的概念,而 srun 不支持。 另一个显著的区别在于容错性。 涉及 sbatch 作业的故障通常导致作业被重新排队并再次执行,而涉及 srun 的故障通常导致生成错误消息,期望用户以适当的方式响应。

任务可以通过远程(伪)终端启动吗?
最佳方法是使用 salloc,并在 slurm.conf 中设置 use_interactive_step。 请参见 在交互模式中获取 shell 提示符

我如何在交互模式中获取 shell 提示符?
从 20.11 开始,获取交互式 shell 提示符的推荐方法是配置 use_interactive_stepslurm.conf 中:

LaunchParameters=use_interactive_step

这会配置 salloc 在调用时自动通过 srun 在分配中的节点上启动一个交互式 shell,前提是没有指定要执行的程序。

默认情况下,use_interactive_step 在分配中的节点上创建一个 交互式步骤,并在该步骤中运行 shell。交互式步骤与批处理步骤的关系类似于交互式 shell 与批处理脚本的关系——两者都可以访问它们运行的节点上的所有资源,但不会 "消耗" 它们。

请注意,从 20.11 开始,srun 创建的步骤现在是独占的。这意味着之前推荐的获取交互式 shell 的方法,srun --pty $SHELL,将不再有效,因为 shell 的步骤将消耗节点上的所有资源,并导致后续的 srun 调用挂起。

一种替代但不推荐的方法是使用 srun 的 --pty 选项(例如 srun --pty bash -i)。 srun 的 --pty 选项以伪终端模式运行任务零。Bash 的 -i 选项指示它以交互模式运行(带提示符)。 但是,与批处理或交互步骤不同,这会启动一个消耗作业中所有资源的步骤。这意味着在作业中无法启动后续步骤,除非它们使用 --overlap 选项。如果配置了任务插件,shell 将仅限于第一个任务的 CPU。后续步骤(必须使用 --overlap 启动)可能会受到比预期更少的资源限制,或者如果请求了多个节点,则可能完全无法启动任务。因此,这种替代方法应该很少使用;应该使用 salloc

Slurm 可以在分配的计算节点上导出 X11 显示吗?
您可以从版本 17.11 开始使用 X11 内置功能。 通过在 slurm.conf 中设置 PrologFlags=x11 来启用它。 其他 X11 插件必须被禁用。
运行示例如下:

$ ssh -X user@login1
$ srun -n1 --pty --x11 xclock

对于旧版本,另一种选择是构建并安装一个可选的 SPANK 插件以实现该功能。以下是构建和安装插件的说明。此 SPANK 插件在与本地 X11 支持结合使用时将无法工作,因此您必须在编译 Slurm 时禁用它,使用 --disable-x11。此插件依赖于 openssh 库,并提供 GSSAPI 支持等功能。
根据需要更新 Slurm 安装路径:

# 这可能很明显,但不要忘记在 ssh 上使用 -X
$ ssh -X alex@testserver.com

# 获取插件
$ mkdir git
$ cd git
$ git clone https://github.com/hautreux/slurm-spank-x11.git
$ cd slurm-spank-x11

# 手动编辑 X11_LIBEXEC_PROG 宏定义
$ vi slurm-spank-x11.c
$ vi slurm-spank-x11-plug.c
$ grep "define X11_" slurm-spank-x11.c
#define X11_LIBEXEC_PROG "/opt/slurm/17.02/libexec/slurm-spank-x11"
$ grep "define X11_LIBEXEC_PROG" slurm-spank-x11-plug.c
#define X11_LIBEXEC_PROG "/opt/slurm/17.02/libexec/slurm-spank-x11"


# 编译
$ gcc -g -o slurm-spank-x11 slurm-spank-x11.c
$ gcc -g -I/opt/slurm/17.02/include -shared -fPIC -o x11.so slurm-spank-x11-plug.c

# 安装
$ mkdir -p /opt/slurm/17.02/libexec
$ install -m 755 slurm-spank-x11 /opt/slurm/17.02/libexec
$ install -m 755 x11.so /opt/slurm/17.02/lib/slurm

# 配置
$ echo -e "optional x11.so" >> /opt/slurm/17.02/etc/plugstack.conf
$ cd ~/tests

# 运行
$ srun -n1 --pty --x11 xclock
alex@node1 的密码:

调度

为什么我的作业没有运行?
这个问题的答案取决于许多因素。主要因素是 Slurm 使用的调度程序。执行命令

scontrol show config | grep SchedulerType

将提供此信息。如果调度程序类型是 builtin,则作业将按提交顺序在给定分区中执行。即使有可用资源可以立即启动您的作业,它也会被推迟,直到没有先前提交的作业在等待。如果调度程序类型是 backfill,则作业通常将按提交顺序在给定分区中执行,但有一个例外:后提交的作业将在不延迟先前提交的作业的预计执行时间的情况下提前启动。为了使回填调度有效,用户的作业应指定合理的时间限制。如果作业没有指定时间限制,则所有作业将获得相同的时间限制(与分区相关的限制),而回填调度作业的能力将受到限制。回填调度程序不会更改所需或排除节点的作业规范,因此指定节点的作业将显著降低回填调度的有效性。有关更多详细信息,请参见 回填 部分。对于任何调度程序,您可以使用命令 scontrol show job 检查作业的优先级。 其他原因可能包括等待资源、内存、qos、预留等。作为指导,发出 scontrol show job <jobid> 并查看 StateReason 字段以调查原因。 不同原因的完整列表和解释可以在 资源限制 页面中找到。

为什么 Slurm 回填调度程序没有启动我的作业?
最常见的问题是未设置作业时间限制。如果所有作业都有相同的时间限制(例如分区的时间限制),则回填将无效。请注意,分区可以同时具有默认和最大时间限制,这在配置系统以有效回填调度时可能会有所帮助。

此外,还有许多回填调度参数可能会影响哪些作业被视为回填调度,例如每个用户测试的最大作业数。有关更多信息,请参见 slurm.conf 手册页,并检查您系统上的 SchedulerParameters 配置。

被终止的作业

为什么我的作业被提前终止?
Slurm 有一个作业清除机制,用于在达到时间限制之前删除不活动的作业(资源分配),该时间限制可能是无限的。 此不活动时间限制由系统管理员配置。 您可以使用命令检查其值

scontrol show config | grep InactiveLimit

InactiveLimit 的值以秒为单位。 零值表示禁用作业清除。 如果作业没有活动的作业步骤,或者创建作业的 srun 命令没有响应,则该作业被视为不活动。 在批处理作业的情况下,srun 命令在作业脚本提交后终止。 因此,批处理作业的前后处理限制在 InactiveLimit 之内。 如果您认为 InactiveLimit 值应该更改,请联系系统管理员。

为什么我没有启动任何作业步骤的批处理作业被终止?
Slurm 有一个配置参数 InactiveLimit,旨在终止在可配置时间段内未生成任何作业步骤的作业。您的系统管理员可以修改 InactiveLimit 以满足您的需求。或者,您可以在脚本开始时生成一个作业步骤以在后台执行。 当您的脚本退出或作业以其他方式终止时,它将被清除。 在脚本开头附近添加一行即可:
srun -N1 -n1 sleep 999999 &

"srun: 强制终止作业" 表示什么?
srun 命令通常在生成的任务的标准输出和错误 I/O 结束时终止。这并不一定发生在作业步骤终止的同一时间。例如,文件系统问题可能会导致生成的任务无法被杀死,同时 I/O 对 srun 正在等待。或者,网络问题可能会阻止 I/O 传输到 srun。 无论如何,当作业步骤终止时,srun 命令会收到通知,无论是达到时间限制还是被明确杀死。如果 srun 尚未终止,则会打印消息 "srun: 强制终止作业"。 如果作业步骤的 I/O 在此后未能及时终止,则挂起的 I/O 将被放弃,srun 命令将退出。

这是什么意思:"srun: 第一个任务在 30 秒前退出",后面跟着 "srun 作业失败"?
这意味着作业的第一个任务在 30 秒前退出,导致整个作业失败。

我如何暂时阻止作业运行(例如,将其置于 hold 状态)?
您可以使用 scontrol 命令将作业置于保持状态,使用命令 scontrol hold

我可以在作业开始运行后更改作业的大小吗?
作业的大小通常在提交时设置,并且在运行时无法更改。您可以通过重新提交作业来更改其大小。

为什么 squeue(和 "scontrol show jobid")有时不显示作业的预计开始时间?
预计开始时间可能会受到资源可用性和调度策略的影响,因此在某些情况下可能不会显示。

squeue 输出可以进行颜色编码吗?
是的,您可以通过设置 squeue 的颜色选项来启用颜色编码。

为什么我的作业/节点处于 COMPLETING 状态?
这通常表示作业正在完成,但可能由于某些原因延迟。请检查作业的状态和日志以获取更多信息。

如何将处于完成或失败状态的作业重新排队?
您可以使用 scontrol 命令将作业重新排队,使用命令 scontrol requeue

为什么 sview 没有正确着色/高亮节点?
这可能是由于配置问题或节点状态未正确更新。请检查 sview 的配置和节点状态。

为什么我的 MPICH2 或 MVAPICH2 作业在 Slurm 中无法运行?为什么 DAKOTA 程序无法在 Slurm 中运行?
这可能是由于配置问题或不兼容的库。请检查您的环境和库设置。

资源限制

管理员相关

测试环境

构建和安装

集群管理

计费数据库

计算节点 (slurmd)

  • 为什么节点在注册服务时显示为 DOWN 状态?
  • 当节点崩溃时会发生什么?
  • 我如何控制每个节点的多个作业的执行?
  • 为什么作业被分配到节点后无法在某些节点上启动程序?
  • 为什么 slurmctld 记录某些节点未响应,即使它们不在任何分区中?
  • 我如何在主要 Slurm 更新之间轻松保留排水节点信息?
  • 是否有人有 Slurm 的节点健康检查脚本示例?
  • 为什么 HealthCheckProgram 不在 DOWN 节点上执行?
  • 我如何防止 slurmdslurmstepd 守护进程在节点内存耗尽时被杀死?
  • 这意味着什么: "srun: 第一个任务在30秒前退出" 后面跟着 "srun 作业失败"?
    srun 命令监控任务何时退出。默认情况下,第一个任务退出后 30 秒,作业将被终止。 这通常表示某种类型的作业失败,当一个任务退出时继续执行并行作业通常没有生产力。可以使用 srun 的 --wait=<time> 选项更改此行为,以更改超时时间或完全禁用超时。有关详细信息,请参见 srun 的手册页。

    管理作业

    我如何暂时阻止作业运行 (例如,将其置于 hold 状态)?
    最简单的方法是更改作业的最早开始时间 (可选地在作业提交时使用 --begin 选项设置)。 下面的示例将作业置于保持状态(阻止其启动 30 天),然后允许其立即启动。

    $ scontrol update JobId=1234 StartTime=now+30days
    ... 稍后 ...
    $ scontrol update JobId=1234 StartTime=now
    

    作业开始运行后,我可以更改作业的大小吗?
    Slurm 支持减少作业大小的能力。 请求更少的硬件资源,并更改分区、qos、预留、许可证等,仅允许对待处理作业进行。

    使用 scontrol 命令通过指定作业的新节点数 (NumNodes=) 或识别希望作业保留的特定节点 (NodeList=) 来更改作业的大小。 任何在作业放弃的节点上运行的作业步骤将被终止,除非使用 --no-kill 选项启动。 更改作业大小后,由 Slurm 创建的一些包含作业环境信息的环境变量将不再有效,应被删除或更改(例如 SLURM_JOB_NUM_NODES、SLURM_JOB_NODELIST 和 SLURM_NTASKS)。 scontrol 命令将生成一个可以执行的脚本,以重置本地环境变量。 您必须保留 SLURM_JOB_ID 环境变量,以便 srun 命令收集有关作业当前状态的信息,并在后续 srun 调用中指定所需的节点和/或任务数。 当作业大小被调整时,将生成一个新的会计记录,显示作业已被重新提交并以新大小重新启动。 下面是一个示例。

    #!/bin/bash
    srun my_big_job
    scontrol update JobId=$SLURM_JOB_ID NumNodes=2
    . slurm_job_${SLURM_JOB_ID}_resize.sh
    srun -N2 my_small_job
    rm slurm_job_${SLURM_JOB_ID}_resize.*
    

    为什么 squeue(和 "scontrol show jobid")有时不显示作业的预计开始时间?
    当配置了回填调度程序时,它会为候选回填的作业提供预计开始时间。 具有依赖关系的待处理作业将没有估计,因为很难预测当它们依赖的作业终止时将可用哪些资源。还要注意,对于预计很快开始的作业,估计会更好,因为大多数正在运行的作业在预计时间之前结束。可能还有其他适用的回填限制。有关更多详细信息,请参见 回填 部分。

    squeue 输出可以进行颜色编码吗?
    squeue 命令输出没有颜色编码,但可以使用其他工具添加颜色。一个这样的工具是 ColorWrapper (https://github.com/rrthomas/cw)。 下面是一个 ColorWrapper 配置文件和输出的示例。

    path /bin:/usr/bin:/sbin:/usr/sbin:<env>
    usepty
    base green+
    match red:default (Resources)
    match black:default (null)
    match black:cyan N/A
    regex cyan:default  PD .*$
    regex red:default ^\d*\s*C .*$
    regex red:default ^\d*\s*CG .*$
    regex red:default ^\d*\s*NF .*$
    regex white:default ^JOBID.*
    

    为什么我的作业/节点处于 COMPLETING 状态?
    当作业正在终止时,作业及其节点都会进入 COMPLETING 状态。 当每个节点上的 Slurm 守护进程确定与作业相关的所有进程已终止时,该节点的状态将更改为 IDLE 或其他适合其他作业使用的状态。 当分配给作业的每个节点都确定与之相关的所有进程已终止时,作业的状态将更改为 COMPLETED 或其他适合的状态(例如 FAILED)。 通常,这在一秒钟内发生。 但是,如果作业有无法通过 SIGKILL 信号终止的进程,作业和一个或多个节点可能会在 COMPLETING 状态下保持较长时间。 这可能表明进程挂起,等待核心文件完成 I/O 或操作系统故障。 如果这种状态持续存在,系统管理员应检查与作业相关的无法终止的进程,然后使用 scontrol 命令将节点的状态更改为 DOWN(例如 "scontrol update NodeName=name State=DOWN Reason=hung_completing"),重启节点,然后将节点的状态重置为 IDLE (例如 "scontrol update NodeName=name State=RESUME")。 请注意,将节点设置为 DOWN 将终止与该节点相关的所有正在运行或挂起的作业。 另一种选择是将节点的状态设置为 DRAIN,直到与其相关的所有作业终止,然后再将其设置为 DOWN 并重启。

    请注意,Slurm 有两个配置参数可用于自动化此过程的一部分。 UnkillableStepProgram 指定在识别到不可杀死的进程时要执行的程序。 UnkillableStepTimeout 指定等待进程终止的时间。 有关这些参数的更多信息,请参见 "man slurm.conf"。

    如何将处于完成或失败状态的作业重新排队?
    Slurm 支持将处于完成或失败状态的作业重新排队。使用以下命令:

    scontrol requeue job_id

    然后作业将重新排队回 PENDING 状态并再次调度。 请参见 man(1) scontrol。

    考虑一个简单的作业,如下所示:

    $cat zoppo
    #!/bin/sh
    echo "hello, world"
    exit 10
    
    $sbatch -o here ./zoppo
    提交批处理作业 10
    

    该作业以 FAILED 状态结束,因为它以非零值退出。我们可以将作业重新排队回 PENDING 状态,作业将再次被调度。

    $ scontrol requeue 10
    $ squeue
          JOBID PARTITION  NAME     USER   ST   TIME  NODES NODELIST(REASON)
          10      mira    zoppo    david  PD   0:00    1   (NonZeroExitCode)
    $ squeue
        JOBID PARTITION   NAME     USER ST     TIME  NODES NODELIST(REASON)
          10      mira    zoppo    david  R    0:03    1      alanz1
    

    Slurm 支持使用以下命令将处于保持状态的作业重新排队:

    scontrol requeuehold job_id

    作业可以处于 RUNNING、SUSPENDED、COMPLETED 或 FAILED 状态,然后再进行重新排队。

    $ scontrol requeuehold 10
    $ squeue
        JOBID PARTITION  NAME     USER ST       TIME  NODES NODELIST(REASON)
        10      mira    zoppo    david PD       0:00      1 (JobHeldUser)
    

    为什么 sview 没有正确着色/高亮节点?
    sview 的颜色编码受 GTK 主题的影响。节点状态网格由按钮小部件组成,某些 GTK 主题未按预期显示颜色设置。更改 GTK 主题可以恢复正确的颜色编码。

    为什么我的 MPICH2 或 MVAPICH2 作业在 Slurm 下无法运行?为什么 DAKOTA 程序在 Slurm 下无法运行?
    用于支持 MPICH2 或 MVAPICH2 的 Slurm 库引用了多种符号。如果这些符号解析到您程序中的函数或变量而不是适当的库,则应用程序将失败。例如 DAKOTA,版本 5.1 及更早版本,包含一个名为 regcomp 的函数,该函数将被使用,而不是 POSIX 正则表达式函数。将 DAKOTA 的函数和引用从 regcomp 重命名为其他名称以使其正常工作。

    资源限制

    为什么我的资源限制没有传播?
    srun 命令执行时,它捕获在 srun 执行的节点上提交时生效的资源限制。 这些限制在启动用户的作业之前传播到分配的节点。 运行在分配节点上的 Slurm 守护进程然后尝试为正在启动的作业建立相同的资源限制。 无法建立这些资源限制的原因有几个。

    • 应用于 Slurm 的 slurmd 守护进程的硬资源限制低于提交主机上用户的软资源限制。通常,slurmd 守护进程由 init 守护进程以操作系统默认限制启动。可以通过在 /etc/sysconfig/slurm 文件中使用 ulimit 命令或启用 PAM 在 Slurm 中 来解决此问题。
    • 在分配节点上,用户的硬资源限制低于从作业提交节点的同一用户的软硬资源限制。建议系统管理员在集群中的所有节点上为用户建立统一的硬资源限制,以防止这种情况发生。
    • slurm.conf 中配置了 PropagateResourceLimits 或 PropagateResourceLimitsExcept 参数,避免传播指定的限制。

    注意:这可能会产生错误消息 "无法传播 RLIMIT_..."。 仅当用户明确指定资源限制应被传播或 srun 命令以详细日志记录 slurmd 守护进程的操作(例如 "srun -d6 ...")时,才会打印错误消息。

    为什么作业没有获得适当的内存限制?
    这可能是上述 锁定内存限制

    为什么我的 MPI 作业因锁定内存(memlock)限制过低而失败?
    默认情况下,Slurm 在作业提交时传播您所有的资源限制到生成的任务。 可以通过在 slurm.conf 文件中明确排除特定限制的传播来禁用此功能。例如,可能使用 PropagateResourceLimitsExcept=MEMLOCK 来防止用户的锁定内存限制从 登录节点 传播到用于其并行作业的专用节点。 如果用户的资源限制未被传播,则将使用 slurmd 守护进程的有效限制。 控制此行为的简单方法是确保用户 root 具有足够大的资源限制,并确保 slurmd 充分利用此限制。例如,您可以将用户 root 的锁定内存限制 ulimit 设置为在计算节点上无限制(请参见 "man limits.conf"),并确保 slurmd 充分利用此限制(例如,通过将 "LimitMEMLOCK=infinity" 添加到您的 systemd 的 slurmd.service 文件)。还可能希望锁定 slurmd 守护进程的内存,以帮助确保在开始内存交换时它保持响应。下面是一个可以从 systemd 读取的示例 /etc/sysconfig/slurm。 有关 PAM 的相关信息也可用。

    #
    # 示例 /etc/sysconfig/slurm
    #
    # 锁定 slurmd 进程的内存,以便如果节点开始交换,slurmd 将继续响应
    SLURMD_OPTIONS="-M"
    

    管理员指南

    测试环境

    可以同时运行多个 Slurm 系统进行测试吗?
    是的,这是测试新版本 Slurm 的好方法。 只需在不同位置安装测试版本,并使用不同的 slurm.conf。 测试系统的 slurm.conf 应指定不同的路径名和端口号以避免冲突。 唯一的问题是如果多个版本的 Slurm 配置了 burst_buffer/* 插件或其他可能与外部系统 API 交互的插件。 在这种情况下,来自不同 Slurm 系统的 API 请求可能会发生冲突。 可以通过将测试系统配置为 burst_buffer/none 来避免这种情况。

    Slurm 可以模拟更大的集群吗?
    是的,这对于测试目的可能很有用。 它还用于将“胖”节点划分为多个 Slurm 节点。 有两种方法可以做到这一点。 对于大多数条件,最好的方法是在集群中每个模拟节点上运行一个 slurmd 守护进程,如下所示。

    1. 在执行 configure 程序时,使用 --enable-multiple-slurmd 选项(或将该选项添加到您的 ~/.rpmmacros 文件中)。
    2. 以通常的方式构建并安装 Slurm。
    3. slurm.conf 中定义所需的节点名称(仅供 Slurm 使用的任意名称)作为 NodeName,以及 NodeHostname 中物理节点的实际地址。多个 NodeName 值可以映射到单个 NodeHostname。请注意,单个物理节点上的每个 NodeName 需要配置为使用不同的端口号(在每行上将 Port 设置为唯一值)。您还希望在 slurm.conf 中的 slurmd 相关路径选项中使用 "%n" 符号(SlurmdLogFileSlurmdPidFile)。
    4. 启动 slurmd 守护进程时,在执行行中包含它应服务的节点的 NodeName(例如 "slurmd -N hostname")。
    5. 这是一个包含模拟节点和端口配置的 slurm.conf 文件示例。可以指定 CPUs、内存或其他有效节点资源的任何有效值。
    NodeName=dummy26[1-100] NodeHostName=achille Port=[6001-6100] NodeAddr=127.0.0.1 CPUs=4 RealMemory=6000
    PartitionName=mira Default=yes Nodes=dummy26[1-100]
    

    有关配置多个 slurmd 支持的更多详细信息,请参见 程序员指南

    Slurm 可以模拟具有比物理上存在的节点更多资源的节点吗?
    是的。在 slurm.conf 文件中,配置 SlurmdParameters=config_overrides 并指定任何所需的节点资源规范(CPUsSocketsCoresPerSocketThreadsPerCore 和/或 TmpDisk)。 Slurm 将使用在 slurm.conf 中给出的每个节点的资源规范,而不会检查这些规范与节点上实际找到的资源是否一致。系统最好配置为 TaskPlugin=task/none,以便启动的任务可以在操作系统控制下在任何可用 CPU 上运行。

    构建与安装

    为什么 pam_slurm.so、auth_none.so 或其他组件不在 Slurm RPM 中?
    在构建时,可能缺少构建库所需的依赖项。如果您想构建该库,请安装 pam-devel 并重新编译。请参见 Slurm 分发中的 slurm.spec 文件,以获取您可以在编译时使用的其他选项列表以及 rpmbuild 标志和您的 rpmmacros 文件。

    auth_none 插件在一个单独的 RPM 中,并且默认情况下不构建。 使用 auth_none 插件意味着 Slurm 通信未经过身份验证,因此您可能不希望在此操作模式下运行,除非用于测试目的。如果您想构建 auth_none RPM,请在 rpmbuild 命令行上添加 --with auth_none,或将 %_with_auth_none 添加到您的 ~/rpmmacros 文件中。请参见 Slurm 分发中的 slurm.spec 文件,以获取其他选项的列表。

    如何构建带有调试符号的 Slurm?
    在配置时,使用 --enable-developer 选项运行配置脚本。 这将提供断言、调试消息和 -Werror 标志,这将激活 --enable-debug
    使用 --enable-debug 标志,代码将使用 -ggdb3-g -O1 -fno-strict-aliasing 标志编译,这将生成额外的调试信息。另一个可能使用的选项是 --disable-optimizations,这将设置 -O0。 有关更多详细信息,请参见 auxdir/x_ac_debug.m4

    如何从 GitHub 中的 Slurm 提交生成补丁文件?
    在 GitHub 中找到并打开提交,然后将 ".patch" 附加到 URL 并保存生成的文件。示例见: https://github.com/SchedMD/slurm/commit/91e543d433bed11e0df13ce0499be641774c99a3.patch

    如何将补丁应用于我的 Slurm 源代码?
    如果您有需要应用于源代码的补丁文件,例如 SchedMD 支持提供的安全或错误修复补丁,您可以使用 patch 命令执行此操作。您首先需要提取您正在使用的版本的源 tarball 的内容。然后可以将补丁应用于提取的源代码。以下是如何使用 Slurm 23.11.1 的源代码执行此操作的示例:

    $ tar xjvf slurm-23.11.1.tar.bz2 > /dev/null
    $ patch -p1 -d slurm-23.11.1/ < example.patch
    patching file src/slurmctld/step_mgr.c
    

    一旦补丁应用于源代码,您可以像往常一样继续构建 Slurm,如果您使用 make 进行构建。如果您使用 rpmbuild 来构建 Slurm,则必须创建一个包含补丁文件的 tarball。tarball 的文件名必须与原始文件名匹配,以避免错误。

    $ tar cjvf slurm-23.11.1.tar.bz2 slurm-23.11.1/ > /dev/null
    $ rpmbuild -ta slurm-23.11.1.tar.bz2 > /dev/null
    

    或者,从 Slurm 24.11.0 开始,在使用 rpmbuild 时,可以通过将补丁文件放在与源 tarball 相同的目录中并执行以下命令直接创建补丁包:

    $ rpmbuild -ta --define 'patch security.patch' slurm-24.11.0.tar.bz2
    

    为什么我会被提供 Slurm 的自动更新?
    EPEL 已将 Slurm 包添加到其存储库,以使其更广泛地提供给 Linux 社区。然而,这个打包版本并不受 SchedMD 支持或维护,目前不建议客户使用。如果您正在使用 EPEL 存储库,您可能会被提供一个您未预期的 Slurm 更新。为了防止 Slurm 被意外升级,我们建议您修改 EPEL 存储库配置文件,以排除所有 Slurm 包的自动更新。

    exclude=slurm*
    

    集群管理

    我应该如何重新定位主控制器或备份控制器?
    如果用于主控制器或备份控制器的集群计算机将长时间停用,可能希望重新定位它们。为此,请按照以下步骤操作:

    1. (Slurm 23.02 及更早版本)将集群中的正在运行作业排空
    2. 停止所有 Slurm 守护进程
    3. slurm.conf 文件中修改 SlurmctldHost
    4. 将更新的 slurm.conf 文件分发到所有节点
    5. StateSaveLocation 目录复制到新主机,并确保权限允许 SlurmUser 读取和写入。
    6. 重新启动所有 Slurm 守护进程

    从 Slurm 23.11 开始,由旧控制器启动的作业将接收更新的控制器地址,并将继续正常完成。 在旧版本中,由旧控制器启动的作业仍将尝试向旧控制器报告。 在这两种情况下,都不应丢失任何待处理作业。 确保添加到集群的任何节点都安装有当前的 slurm.conf 文件。

    注意:如果两个节点同时配置为主控制器(两个节点的 SlurmctldHost 指定本地主机,并且每个节点上都在执行 slurmctld 守护进程),系统行为将是破坏性的。如果计算节点的 SlurmctldHost 参数不正确,则该节点可能会变得不可用,但不会造成其他损害。

    我需要在集群中维护同步时钟吗?
    一般来说,是的。时钟不一致可能导致节点无法使用,并在 Slurm 日志文件中生成有关凭证过期的错误。例如:

    error: Munge decode failed: Expired credential
    ENCODED: Wed May 12 12:34:56 2008
    DECODED: Wed May 12 12:01:12 2008
    

    我如何停止 Slurm 调度作业?
    您可以通过将该分区的状态设置为 DOWN 来停止 Slurm 在每个分区上调度作业。将其状态设置为 UP 以恢复调度。 例如:

    $ scontrol update PartitionName=foo State=DOWN
    $ scontrol update PartitionName=bar State=UP
    

    我如何在维护期间减少工作负载?
    创建资源预留,如 Slurm 的 资源预留指南 中所述。

    升级 Slurm 时我应该注意什么?
    有关详细信息,请参见 升级指南

    升级我的数据库服务器时,有什么特别需要注意的吗?
    一般来说,没有。特殊情况在升级指南的 数据库服务器 部分中有说明。

    添加新集群时,如何将 Slurm 集群配置从现有集群复制到新集群?
    需要为集群配置帐户。复制现有集群信息的简单方法是使用 sacctmgr 命令转储该集群的信息,使用某些编辑器修改它,然后使用 sacctmgr 命令加载新信息。有关详细信息,包括示例,请参见 sacctmgr 手册页。

    为什么在 slurmctld 守护进程崩溃之前立即提交的一些作业会丢失?
    任何时候,如果 slurmctld 守护进程或硬件在状态信息到达磁盘之前失败,都可能导致状态丢失。 Slurmctld 会频繁写入状态(默认每五秒一次),但在作业数量较多时,记录的格式化和写入可能需要几秒钟,最近的更改可能未写入磁盘。 另一个例子是,如果状态信息写入文件,但该信息在节点失败时被缓存到内存中而不是写入磁盘。 状态保存写入磁盘的间隔可以在构建时通过将 SAVE_MAX_WAIT 定义为与五不同的值进行配置。

    资源限制传播在同质集群中有用吗?
    资源限制传播允许用户修改资源限制并提交具有这些限制的作业。 默认情况下,Slurm 会自动将作业提交时生效的所有资源限制传播到作为该作业一部分生成的任务。 系统管理员可以利用 PropagateResourceLimitsPropagateResourceLimitsExcept 配置参数来更改此行为。 用户可以使用 srun --propagate 选项覆盖默认设置。 有关这些选项的更多信息,请参见 "man slurm.conf""man srun"

    为什么数据库中设置的资源限制未被强制执行?
    为了强制执行资源限制,请在每个集群的 slurm.conf 配置文件中适当地设置 AccountingStorageEnforce 的值。如果 AccountingStorageEnforce 不包含 "limits" 的选项,则不会在该集群上强制执行资源限制。 有关更多信息,请参见 资源限制

    Slurm 可以配置为管理许可证吗?
    Slurm 不提供与第三方许可证管理器的本地集成,但它确实提供了分配称为许可证的全局资源的功能。 在您的 slurm.conf 文件中使用许可证配置参数(例如 "Licenses=foo:10,bar:20")。作业可以请求许可证并获得对这些资源的独占使用权(例如 "sbatch --licenses=foo:2,bar:1 ...")。 目前无法在不重启 slurmctld 守护进程的情况下更改系统上的许可证总数,但可以动态保留许可证并将其从系统中移除(例如 "scontrol update reservation=licenses_held licenses=foo:5,bar:2")。 有关更多信息,请参见 许可证指南

    从 PBS 或 Torque 切换到 Slurm 有多简单?
    许多用户甚至没有注意到区别。 Slurm 提供了 mpiexec、pbsnodes、qdel、qhold、qrls、qstat 和 qsub 命令的包装器(请参见分发中的 contribs/torque 和 "slurm-torque" RPM)。 在 https://github.com/pedmon/slurm_showq 处还有 showq 命令的包装器。

    Slurm 识别并转换批处理脚本中的 "#PBS" 选项。 大多数,但不是所有选项都受支持。

    Slurm 还包括一个 SPANK 插件,该插件将根据 Slurm 环境设置所有 PBS 环境变量(例如 PBS_JOBID、PBS_JOBNAME、PBS_WORKDIR 等)。 PBS_ENVIRONMENT 未设置的一个环境变量,如果设置将导致某些 MPI 实现失败。 该插件将安装在
    <install_directory>/lib/slurm/spank_pbs.so
    有关配置详细信息,请参见 SPANK 手册页。

    是什么原因导致 MPI 性能低于预期水平?
    以有限的锁定内存启动 slurmd 守护进程可能导致这种情况。 在 /etc/sysconfig/slurm 文件中添加 "ulimit -l unlimited" 行可以解决此问题。

    我如何安全地删除分区?
    应使用 "scontrol delete PartitionName=<partition>" 命令删除分区。这是因为 scontrol 将阻止删除任何正在使用的分区。 在使用 scontrol 删除后,需要从 slurm.conf 中删除分区,否则它们将在重启后返回。 可以使用 "scontrol update JobId=<jobid> Partition=<partition(s)>" 命令更新现有作业的分区。 从 slurm.conf 中删除分区并重启将取消任何引用已删除分区的现有作业。

    如何配置路由队列?
    作业提交插件旨在访问来自用户的作业请求,以及有关所有可用系统分区/队列的信息。 管理员可以编写 C 插件或 LUA 脚本,根据作业的大小、时间限制等设置传入作业的分区。 有关更多信息,请参见 作业提交插件 API 指南。 还可以查看与 Slurm 一起分发的可用作业提交插件的示例(请查看 "src/plugins/job_submit" 目录)。

    "none" 插件发生了什么?
    在 Slurm 23.02 及更早版本中,几个参数有一个名为 "none" 的插件,基本上会禁用该设置。在 23.11 版本中,已删除名为 "none" 的插件。要禁用设置,只需将其保持未设置。如果您仍然定义了一个插件为 "none",Slurm 仍会识别它并将其视为未设置。以前有 "none" 插件的参数有:

    • AccountingStorageType
    • AcctGatherEnergyType
    • AcctGatherInterconnectType
    • AcctGatherFilesystemType
    • AcctGatherProfileType
    • CliFilterPlugins
    • CoreSpecPlugin
    • ExtSensorsType
    • JobAcctGatherType
    • JobCompType
    • JobContainerType
    • MCSPlugin
    • MpiDefault
    • PowerParameters
    • PreemptType
    • PrioritySiteFactorPlugin
    • SwitchType
    • TaskPlugin
    • TopologyPlugin

    会计数据库

    为什么我应该使用 slurmdbd 而不是常规数据库插件?
    虽然正常存储插件在没有 slurmdbd 的附加层的情况下也能正常工作,但使用 slurmdbd 有一些很大的好处。

    1. 增加安全性。使用 slurmdbd,您可以与数据库建立经过身份验证的连接。
    2. 将处理卸载到控制器。使用 slurmdbd,控制器不会因慢或过载的数据库而减速。
    3. 将所有 Slurm 集群的企业范围会计保存在一个数据库中。 slurmdbd 是多线程的,旨在处理整个企业的所有会计。
    4. 使用数据库插件,您可以从安装了 Slurm 的任何节点查询 sacct 会计统计信息。使用 slurmdbd,您还可以从任何其他集群的节点查询任何集群。
    5. 其他工具,如 sreport 也可用。

  • 如何重建数据库层次结构?
    如果您在 slurmctld 日志文件中看到此类错误:

    error: Can't find parent id 3358 for assoc 1504, this should never happen.
    

    这表明数据库层次结构信息已损坏,通常是由于硬件故障或管理员直接修改数据库时出错。为了重建数据库信息,请使用 "-R" 选项启动 slurmdbd 守护进程,后面跟着一个可选的以逗号分隔的集群名称列表。

    为我的数据库配置高可用性有多重要?

    • 考虑您是否真的需要高可用性 MySQL 设置。slurmdbd 的短暂停机不是问题,因为 slurmctld 将在内存中存储所有数据,并在恢复操作时将其发送到 slurmdbd。slurmctld 守护进程还将缓存所有用户限制和公平共享信息。
    • 您不能使用 NDB,因为 SlurmDBD 的 MySQL 实现使用 BLOB 值上的键(以及潜在的其他不兼容列表中的功能)。
    • 您可以设置“经典”的 Linux HA,使用 heartbeat/corosync 在主/备份 mysql 服务器之间迁移 IP,并:
      • 配置 mysql 的单向复制,并在故障时更改主/备份角色
      • 为主/备份 mysql 服务器数据库使用共享存储,并在主 mysql 故障时启动备份。

    我如何在 MySQL 查询中使用双引号?
    执行:

    SET session sql_mode='ANSI_QUOTES';
    

    这将允许在查询中使用双引号,例如:

    show columns from "tux_assoc_table" where Field='is_def';
    

    计算节点 (slurmd)

    为什么节点在注册服务时显示为 DOWN 状态?
    配置参数 ReturnToServiceslurm.conf 中控制 DOWN 节点的处理方式。 将其值设置为 1,以便 DOWN 节点在 slurmd 守护进程使用有效的节点配置注册后自动返回服务。 默认值为 0,导致节点保持 DOWN 状态,直到管理员使用命令 "scontrol update NodeName=whatever State=RESUME" 显式将其返回服务。 有关更多详细信息,请参见 "man slurm.conf" 和 "man scontrol"。

    节点崩溃时会发生什么?
    当其上的 slurmd 守护进程在 slurm.conf 中定义的 SlurmdTimeout 内停止响应时,节点将被设置为 DOWN。 当发生某些错误或节点的配置与 slurm.conf 中定义的不一致时,也可以将节点设置为 DOWN。 该节点上的任何活动作业将被终止,除非它是使用 srun 选项 --no-kill 提交的。 该节点上的任何活动作业步骤将被终止。 有关更多信息,请参见 slurm.conf 和 srun 手册页。

    如何控制每个节点执行多个作业?
    有两种机制可以控制这一点。 如果您希望将节点上的单个处理器分配给作业,请配置 SelectType=select/cons_tres。 有关此配置的详细信息,请参见 Slurm 中的可消耗资源。 如果您希望将整个节点分配给作业,请配置 SelectType=select/linear。 每个分区还有一个配置参数 OverSubscribe,允许每个节点上执行多个作业。 有关这些配置参数的更多信息,请参见 man slurm.conf

    为什么作业被分配节点后无法在某些节点上启动程序?
    这通常表明某些节点的时间与 slurmctld 守护进程执行的节点不一致。为了 启动作业步骤(或批处理作业),slurmctld 守护进程生成一个包含时间戳的凭证。如果 slurmd 守护进程 收到的凭证包含的时间戳晚于当前时间或早于几分钟,它将被拒绝。 如果您检查感兴趣节点上的 SlurmdLogFile,您可能会看到此类消息:“来自 <某个 IP 地址> 的作业凭证无效:作业凭证过期。”确保所有节点的时间一致,一切都会正常。

    为什么 slurmctld 记录某些节点未响应,即使它们不在任何分区中?
    slurmctld 守护进程定期 ping 每个配置节点上的 slurmd 守护进程,即使它不与任何分区关联。您可以通过 slurm.conf 中的 SlurmdTimeout 配置参数控制此 ping 的频率。

    我如何轻松保留主要 Slurm 更新之间的排水节点信息?
    主要 Slurm 更新通常会更改状态保存文件和通信协议,因此通常需要冷启动(没有状态)。如果您有处于 DRAIN 状态的节点并希望保留该信息,您可以轻松构建一个脚本来保留该信息,使用 sinfo 命令。以下命令行将报告每个 DRAIN 状态节点的 Reason 字段,并以可以稍后执行以恢复状态的形式写入输出。

    sinfo -t drain -h -o "scontrol update nodename='%N' state=drain reason='%E'"
    

    有没有人有 Slurm 的节点健康检查脚本示例?
    可能最全面且轻量的健康检查工具是 节点健康检查。 它与 Slurm 以及 Torque 资源管理器集成。

    为什么 HealthCheckProgram 不在 DOWN 节点上执行?
    用于发送此消息的分层通信。如果通信层次结构中存在 DOWN 节点,则需要重新路由消息。这限制了 Slurm 在整个集群中紧密同步执行 HealthCheckProgram 的能力,这可能会对并行应用程序的性能产生不利影响。 使用 CRON 或节点启动脚本可能更适合确保在 Slurm 中 DOWN 的节点上执行 HealthCheckProgram

    我如何防止 slurmdslurmstepd 守护进程在节点内存耗尽时被杀死?
    您可以通过将 slurmd 守护进程与 SLURMD_OOM_ADJ 和/或 SLURMSTEPD_OOM_ADJ 环境变量设置为所需值来设置 /proc/self/oom_adj 中的值。 通常,-17 的值将禁用杀死。

    我看到调用节点的主机为 127.0.1.1,而不是正确的 IP 地址。为什么会这样?
    某些系统默认会将您的主机放在 /etc/hosts 文件中,类似于:

    127.0.1.1	snowflake.llnl.gov	snowflake
    

    这将导致 srun 和 Slurm 命令使用 127.0.1.1 地址,而不是正确的地址,从而阻止节点之间的通信。 解决方案是删除此行或配置其他节点已知的 NodeAddr。

    CommunicationParameters=NoInAddrAny 配置参数也存在同样的问题,可以通过从 /etc/hosts 文件中的 "127.0.1.1" 和 "127.0.0.1" 中删除实际节点名称来解决。指向 localhost 是可以的,但不能是节点的实际名称。

    我应该如何向 Slurm 添加节点?
    slurmctld 守护进程有许多位图来跟踪集群中节点和核心的状态。向运行中的集群添加节点将要求 slurmctld 守护进程重建所有这些位图,这在旧版本的 Slurm 中需要重启守护进程。来自计算节点上的 slurmd 守护进程到 slurmctld 守护进程的通信包括配置文件校验和,因此您应该在所有节点上保持相同的 slurm.conf 文件。

    以下程序适用于 Slurm 24.05 及更早版本(请参见下面的 24.11 及更高版本):

    1. 停止 slurmctld 守护进程(例如 systemctl stop slurmctld 在头节点上)
    2. 更新集群中所有节点上的 slurm.conf 文件
    3. 重新启动所有节点上的 slurmd 守护进程(例如 systemctl restart slurmd 在所有节点上)
    4. 重新启动 slurmctld 守护进程(例如 systemctl start slurmctld 在头节点上)

    以下程序适用于 Slurm 24.11 及更高版本:

    1. 更新集群中所有节点上的 slurm.conf 文件
    2. 运行 scontrol reconfigure

    注意:在将新节点添加到 slurm.conf 之前,使用 srun 提交的作业并等待分配的作业可能会失败,如果作业分配了新节点之一。

    我应该如何从 Slurm 中删除节点?
    要安全地从集群中删除节点,最好将节点排空所有作业。 这确保在删除后作业进程不会在节点上运行。在控制器重启时,如果节点从正在运行的作业中删除,控制器将在任何剩余分配的节点上终止作业,并在可能的情况下尝试重新排队作业。

    以下程序适用于 Slurm 24.05 及更早版本(请参见下面的 24.11 及更高版本):

    1. 将节点排空所有作业(例如 scontrol update nodename='%N' state=drain reason='removing nodes'
    2. 停止 slurmctld 守护进程(例如 systemctl stop slurmctld 在头节点上)
    3. 更新集群中所有节点上的 slurm.conf 文件
    4. 重新启动所有节点上的 slurmd 守护进程(例如 systemctl restart slurmd 在所有节点上)
    5. 重新启动 slurmctld 守护进程(例如 systemctl start slurmctld 在头节点上)

    以下程序适用于 Slurm 24.11 及更高版本:

    1. 将节点排空所有作业(例如 scontrol update nodename='%N' state=drain reason='removing nodes'
    2. 更新集群中所有节点上的 slurm.conf 文件
    3. 运行 scontrol reconfigure

    注意:从集群中删除节点可能会导致日志中出现一些错误。请确认日志中的任何错误都是您打算删除的节点。

    为什么计算节点的状态为 DOWN,原因设置为 "节点意外重启"?
    这表明集群头节点上的 slurmctld 守护进程以及计算节点上的 slurmd 守护进程在计算节点重启时运行。 如果您希望防止此条件将节点设置为 DOWN 状态,请将 ReturnToService 配置为 2。有关详细信息,请参见 slurm.conf 手册页。 否则,请使用 scontrol 或 sview 手动将节点返回服务。

    我如何将我的节点转换为控制组(cgroup)v2?
    请参阅 cgroup v2 文档以获取转换过程。

    Slurm 可以用于在亚马逊 EC2 上运行作业吗?
    是的,以下是 Slurm 与 亚马逊 EC2 一起使用的描述,感谢 Ashley Pittman:

    我定期这样做,并且没有问题,我采取的方法是启动我想要的尽可能多的实例,并在 ec2-describe-instances 周围有一个包装器,该包装器构建一个具有固定主机名和实际分配的 IP 地址的 /etc/hosts 文件。然后唯一的其他步骤是根据您选择今天启动的节点数量生成 slurm.conf。我在我的笔记本电脑上运行这个包装脚本,它生成文件并自动将它们 rsync 到所有实例。

    我发现的一件事是,如果 slurm.conf 文件中指定的任何节点无法解析,Slurm 拒绝启动,我最初尝试在 slurm.conf 中指定 cloud[0-15],但如果我在 /etc/hosts 中配置少于 16 个节点,这将不起作用,因此我动态生成 slurm.conf 以及 hosts 文件。

    关于 EC2 的评论是,我只运行通用 AMI,并且有一个持久的 EBS 存储设备,当我启动时将其附加到第一个实例。这包含一个 /usr/local,其中安装了我的软件,如 Slurm、pdsh 和 MPI,然后我将其复制到第一个实例的 /usr/local,并通过 NFS 导出到所有其他实例。这样,我就有了持久的主目录和一个非常简单的首次登录脚本,可以为我配置虚拟集群。

    用户管理

    PAM 如何用于控制用户在计算节点上的限制或访问?
    要控制用户在计算节点上的限制:

    首先,通过在 slurm.conf 中设置 UsePAM=1 启用 Slurm 使用 PAM。

    其次,在 /etc/pam.conf/etc/pam.d 目录中的适当文件(例如 /etc/pam.d/sshd)中为 Slurm 建立 PAM 配置文件,通过添加行 "account required pam_slurm.so"。 您可能使用的基本配置如下:

    account  required  pam_unix.so
    account  required  pam_slurm.so
    auth     required  pam_localuser.so
    session  required  pam_limits.so
    

    第三,在 /etc/security/limits.conf 中设置所需的限制。 例如,要将所有用户的锁定内存限制设置为无限制:

    *   hard   memlock   unlimited
    *   soft   memlock   unlimited
    

    最后,您需要禁用 Slurm 从启动作业的会话传播限制。默认情况下,所有资源限制都从该会话传播。例如,将以下行添加到 slurm.conf 将防止锁定内存限制被传播:PropagateResourceLimitsExcept=MEMLOCK

    要控制用户对计算节点的访问:

    pam_slurm_adopt 和 pam_slurm 模块防止用户登录到未分配给他们的节点(root 用户除外,root 用户始终可以登录)。 这两个模块都包含在 Slurm 分发中。

    强烈建议大多数安装使用 pam_slurm_adopt 模块,并在其 自己的指南 中进行了文档说明。

    pam_slurm 较旧且功能较少。 这些模块默认为 RPM 包构建,但可以使用 .rpmmacros 选项 "%_without_pam 1" 禁用,或者在执行 configure 程序时输入命令行选项 "--without pam"。 它们的源代码分别位于 "contribs/pam" 和 "contribs/pam_slurm_adopt" 目录中。

    使用 pam_slurm_adopt 或 pam_slurm 都不需要设置 UsePAM。这两种 PAM 的使用是独立的。

    我如何将某些用户排除在 pam_slurm 之外?
    注意:请在实际在您的 Slurm 计算机上执行此操作之前,在测试机器/虚拟机上进行测试。

    步骤 1. 确保 pam_listfile.so 在您的系统上存在。 以下命令是 Redhat 6 上的示例:

    ls -la /lib64/security/pam_listfile.so
    

    步骤 2. 创建用户列表(例如 /etc/ssh/allowed_users):

    # /etc/ssh/allowed_users
    root
    myadmin
    

    并且,将文件模式更改为使其对普通用户保密(可选):

    chmod 600 /etc/ssh/allowed_users
    

    注意:root 不一定需要列在 allowed_users 中,但如果它在列表中,我会觉得稍微安全一些。

    步骤 3. 在 /etc/pam.d/sshd 中,在 pam_slurm.so 之前添加 pam_listfile.so 和足够的标志(例如,我的 /etc/pam.d/sshd 看起来像这样):

    #%PAM-1.0
    auth       required     pam_sepermit.so
    auth       include      password-auth
    account    sufficient   pam_listfile.so item=user sense=allow file=/etc/ssh/allowed_users onerr=fail
    account    required     pam_slurm.so
    account    required     pam_nologin.so
    account    include      password-auth
    password   include      password-auth
    # pam_selinux.so close 应该是第一个会话规则
    session    required     pam_selinux.so close
    session    required     pam_loginuid.so
    # pam_selinux.so open 仅应跟随在用户上下文中执行的会话
    session    required     pam_selinux.so open env_params
    session    optional     pam_keyinit.so force revoke
    session    include      password-auth
    

    (信息由 Koji Tanaka 提供,印第安纳大学)

    用户的账户可以在数据库中更改吗?
    用户的账户不能直接更改。需要为用户创建与新账户的新关联。然后可以删除与旧账户的关联。

    # 假设用户 "adam" 最初在账户 "physics" 中
    sacctmgr create user name=adam cluster=tux account=physics
    sacctmgr delete user name=adam cluster=tux account=chemistry
    

    我不得不更改用户的 UID,现在他们无法提交作业。我该如何使新的 UID 生效?
    更改 UID 时,您还需要重新启动 slurmctld 以使更改生效。通常,当将新用户添加到系统时,UID 会自动并立即填写。如果用户尚未在系统上被识别,则每小时运行的线程会在用户被识别时填写这些 UID,但它不会识别已存在用户的 UID 更改。但您可以简单地重新启动 slurmctld,以便识别这些更改。

    如何使 SSSD 与 Slurm 一起工作?
    SSSD 或系统安全服务守护程序默认不允许枚举组成员。请注意,在大型环境中启用枚举可能不可行。然而,Slurm 除了一些特定的奇特配置(多个组具有相同的 GID)外,并不需要枚举,因此将枚举禁用可能是安全的。SSSD 默认对某些配置区分大小写,这可能会引发其他问题。将以下行添加到/etc/sssd/sssd.conf 中以解决这些问题:

    enumerate = True
    case_sensitive = False
    

    作业

    作业挂起/恢复有什么用?
    作业挂起/恢复最有用的是能够及时启动特别大的作业,并且开销最小。假设您想启动一个全系统作业。通常,您需要取消所有正在运行的作业或等待它们终止。取消作业会导致从开始到那一点的工作丢失。等待作业终止可能需要几个小时,具体取决于您的系统配置。一个更具吸引力的替代方案是挂起正在运行的作业,运行全系统作业,然后恢复挂起的作业。这可以通过配置一个专门的全系统作业队列并使用脚本来控制该过程轻松实现。该脚本将停止其他分区,挂起这些分区中正在运行的作业,并启动全系统分区。当需要时,该过程可以反转。可以有效地使用此机制进行作业的联合调度(时间切片),尽管实现这些算法可能会变得相当复杂。挂起和恢复作业分别使用 SIGSTOP 和 SIGCONT 信号,因此交换和磁盘空间应足够容纳分配给节点的所有作业,无论是运行还是挂起。

    如何挂起、恢复、保持或释放属于特定用户、分区等的所有作业?
    scontrol 命令中没有可用的按用户、分区等进行过滤的功能;但是可以使用 squeue 命令进行过滤并构建一个可以执行的脚本。例如:

    $ squeue -u adam -h -o "scontrol hold %i" >hold_script
    

    在手动设置作业优先级值后,如何将其优先级值恢复为由优先级/多因素插件管理?
    如下面所示,保持并释放作业。

    $ scontrol hold <jobid>
    $ scontrol release <jobid>
    

    我可以使用单个 scontrol 命令更新多个作业吗?
    不可以,但您可以使用 squeue 构建脚本,利用其过滤和格式选项。例如:

    $ squeue -tpd -h -o "scontrol update jobid=%i priority=1000" >my.script
    

    我如何自动将作业的 Slurm 作业 ID 打印到其标准输出?
    配置的 TaskProlog 是唯一可以写入作业的标准输出或为作业或作业步骤设置额外环境变量的东西。要写入作业的标准输出,请在消息前加上 "print "。要导出环境变量,请输出一行形式为 "export name=value"。下面的示例将仅打印批处理作业的 Slurm 作业 ID 和分配的主机。

    #!/bin/sh
    #
    # 示例 TaskProlog 脚本,将打印批处理作业的
    # 作业 ID 和节点列表到作业的标准输出
    #
    
    if [ X"$SLURM_STEP_ID" = "X" -a X"$SLURM_PROCID" = "X"0 ]
    then
      echo "print =========================================="
      echo "print SLURM_JOB_ID = $SLURM_JOB_ID"
      echo "print SLURM_JOB_NODELIST = $SLURM_JOB_NODELIST"
      echo "print =========================================="
    fi
    

    是否可以写入用户标准输出?
    Slurm 处理用户 I/O 的方式使得在用户进程执行后作为管理员无法写入用户进程(execve 被调用)。这发生在调用 TaskProlog 之后,这是我们可以写入用户进程标准输出的最后时刻。Slurm 假设该文件描述符在运行时仅由用户进程拥有。文件描述符按指定方式打开并传递给任务,因此它直接使用该文件描述符。Slurmstepd 能够通过复制进程的标准错误将错误消息记录到错误文件中。

    可以从 SPANK 插件写入标准错误,但这不能用于附加作业摘要,因为文件描述符是以 close-on-exec 标志打开的,并且在用户进程完成后,操作系统会立即关闭它们。理论上,可以使用 EpilogSlurmctld 作为准备某种作业摘要的中心位置。然而,使用它写入存储用户输出的文件可能会有问题。该脚本以 SlurmUser 身份运行,因此可能需要对文件名进行严格验证(例如,防止用户指定类似 /etc/passwd 的输出文件)。作业可能还有多个输出文件(请参见 文件名模式 在 srun 手册页中)。

    为什么用户进程和 srun 仍在运行,即使作业应该已完成?
    Slurm 依赖可配置的进程跟踪插件来确定与作业或作业步骤关联的所有进程何时完成。依赖内核补丁的插件可以可靠地识别每个进程。依赖于进程组 ID 或父进程 ID 的插件则不可靠。有关详细信息,请参见 ProctrackType 描述在 slurm.conf 手册页中。我们依赖于大多数系统的 cgroup 插件。

    如何将以特定退出代码退出的作业重新排队?
    Slurm 支持在保持状态下使用 SPECIAL_EXIT 状态重新排队,使用以下命令:

    scontrol requeuehold State=SpecialExit job_id

    当用户希望重新排队并标记以特定错误情况退出的作业时,这非常有用。有关更多详细信息,请参见手册 scontrol(1)。

    $ scontrol requeuehold State=SpecialExit 10
    $ squeue
       JOBID PARTITION  NAME     USER  ST       TIME  NODES NODELIST(REASON)
        10      mira    zoppo    david SE       0:00      1 (JobHeldUser)
    

    该作业可以稍后释放并再次运行。

    退出时以特定退出代码退出的作业的重新排队可以使用 EpilogSlurmctld 自动化,参见手册(5) slurm.conf。 这是一个示例脚本,其退出代码取决于文件的存在。

    $ cat exitme
    #!/bin/sh
    #
    echo "hi! `date`"
    if [ ! -e "/tmp/myfile" ]; then
      echo "going out with 8"
      exit 8
    fi
    rm /tmp/myfile
    echo "going out with 0"
    exit 0
    

    这是一个检查作业退出值的 EpilogSlurmctld 示例,查看 SLURM_JOB_EXIT2 环境变量,如果它以值 8 退出,则重新排队该作业。SLURM_JOB_EXIT2 的格式为 "exit:sig",第一个数字是退出代码,通常由 exit() 函数设置。 第二个数字是导致进程终止的信号(如果是由信号终止的话)。

    $ cat slurmctldepilog
    #!/bin/sh
    
    export PATH=/bin:/home/slurm/linux/bin
    LOG=/home/slurm/linux/log/logslurmepilog
    
    echo "Start `date`" >> $LOG 2>&1
    echo "Job $SLURM_JOB_ID exitcode $SLURM_JOB_EXIT_CODE2" >> $LOG 2>&1
    exitcode=`echo $SLURM_JOB_EXIT_CODE2|awk '{split($0, a, ":"); print a[1]}'` >> $LOG 2>&1
    if [ "$exitcode" == "8" ]; then
       echo "Found REQUEUE_EXIT_CODE: $REQUEUE_EXIT_CODE" >> $LOG 2>&1
       scontrol requeuehold state=SpecialExit $SLURM_JOB_ID >> $LOG 2>&1
       echo $? >> $LOG 2>&1
    else
       echo "Job $SLURM_JOB_ID exit all right" >> $LOG 2>&1
    fi
    echo "Done `date`" >> $LOG 2>&1
    
    exit 0
    

    以 exitme 脚本为例,我们让它在第一次运行时以值 8 退出,然后当它在保持状态下以 SpecialExit 状态重新排队时,我们触摸文件 /tmp/myfile,然后释放作业,这将以 COMPLETE 状态完成。

    为什么 Slurm 无法为作业设置 CPU 频率?
    首先检查 Slurm 是否配置为将作业绑定到特定 CPU,确保 TaskPlugin 配置为 affinity 或 cgroup。接下来检查您的处理器是否配置为允许频率控制,通过检查文件 /sys/devices/system/cpu/cpu0/cpufreq 中的值,其中 "cpu0" 代表 CPU ID 0。特别关注文件 scaling_available_governors,该文件标识可用的 CPU 调节器。如果 "userspace" 不是可用的 CPU 调节器,则可能是由于安装了 intel_pstate 驱动程序。有关禁用 intel_pstate 驱动程序的信息可在
    https://bugzilla.kernel.org/show_bug.cgi?id=57141
    http://unix.stackexchange.com/questions/121410/setting-cpu-governor-to-on-demand-or-conservative 中找到。

    salloc 命令可以配置为在作业分配的节点上启动一个 shell 吗?
    是的,只需在 slurm.conf 中将 "use_interactive_step" 作为 LaunchParameters 配置选项的一部分进行设置。

    如何为我机器上的作业设置私有 /tmp 和 /dev/shm?
    Tmpfs 作业容器插件可以通过在 slurm.conf 文件中包含 JobContainerType=job_container/tmpfs 来使用。它还需要设置一个 job_container.conf 文件,具体描述在手册页中。Tmpfs 插件创建一个私有挂载命名空间,在其中挂载一个私有 /tmp 到 job_container.conf 中配置的位置。基路径用于构造挂载路径,通过在其中创建一个特定于作业的目录并将 /tmp 挂载到该目录。由于所有挂载都是在一个私有的挂载命名空间内部创建的,因此它们仅在作业内部可见。因此,这为在共享节点上的作业提供了一个有用的解决方案,因为每个作业只能查看在其自己的挂载命名空间中创建的挂载。一个私有的 /dev/shm 也被挂载,以在不同作业之间隔离它。

    挂载命名空间的构造也发生在作业的 spank 环境设置之前。因此,所有与 spank 相关的作业步骤将仅查看插件创建的私有 /tmp。该插件还提供一个可选的初始化脚本,该脚本在作业的命名空间构造之前被调用。这对于可能需要的任何特定于站点的自定义非常有用。

    parallels@linux_vb:~$ echo $SLURM_JOB_ID
    7
    parallels@linux_vb:~$ findmnt -o+PROPAGATION | grep /tmp
    └─/tmp  /dev/sda1[/storage/7/.7] ext4  rw,relatime,errors=remount-ro,data=ordered   private
    

    在上面的示例中,BasePath 指向 /storage,并且作业 ID 为 7 的 slurm 作业被设置为将 /tmp 挂载到 /storage/7/.7。当用户在作业内部尝试查看挂载时,他们可以看到他们的 /tmp 被挂载。然而,他们被阻止错误地直接访问后备目录。

    parallels@linux_vb:~$ cd /storage/7/
    bash: cd: /storage/7/: Permission denied
    

    他们仅被允许访问(读/写)/tmp。

    此外,pam_slurm_adopt 也已扩展以支持此功能。如果用户启动一个由 pam_slurm_adopt 管理的 ssh 会话,则用户的进程将加入由 tmpfs 插件构建的命名空间。因此,在 ssh 会话中,用户对 /tmp 和 /dev/shm 的视图与他们的作业相同。此功能在 pam_slurm_adopt 中默认启用,但可以通过附加 join_container=false 显式禁用,如下所示:

    account	sufficient  pam_slurm_adopt.so join_container=false
    

    如何配置 Slurm 以与启用 System V IPC 的应用程序一起工作?
    Slurm 通常对 System V IPC(也称为 Linux 内核中的 "sysv ipc")是无关的。 使用 sysv ipc 的进程的内存计数取决于 sysctl kernel.shm_rmid_forced 的值(在 Linux 内核 3.1 中添加):

    • shm_rmid_forced = 1
      强制所有进程的共享内存使用被内核计入并报告给 Slurm。这会破坏 sysv ipc 的单独命名空间,并可能在没有仔细规划的情况下导致意外的应用程序问题。跨作业共享相同 sysv ipc 命名空间的进程可能会在另一个作业结束时被 OOM 杀死,并且它们的分配百分比增加。
    • shm_rmid_forced = 0(大多数 Linux 发行版的默认值)
      Slurm 不会报告作业的 System V 内存使用。 通常建议配置 sysctl kernel.shmmax 参数。kernel.shmmax 的值乘以作业进程的最大数量应从每个节点的 slurm.conf 中配置的 RealMemory 中扣除。大多数 Linux 发行版将默认值设置为有效上限,这可能会导致 OOM 杀手在不相关的新作业或甚至 slurmd 进程上激活。如果任何进程使用 sysv 内存机制,Linux 内核的 OOM 杀手将永远无法释放使用的内存。需要一个 Slurm 作业 epilog 脚本来释放任何用户内存。将 kernel.shmmax=0 设置为禁用 sysv ipc 内存分配,但可能会导致应用程序问题。

    常规故障排除

    如果 Slurm 守护进程核心转储,我在哪里可以找到核心文件?
    如果 slurmctld 是使用 -D 选项启动的,则核心文件将写入当前工作目录。如果 SlurmctldLogFile 是绝对路径,则核心文件将写入该目录。否则,核心文件将写入 StateSaveLocation,或者最后的选择是 "/var/tmp/"。
    SlurmUser 必须对这些目录具有写权限。如果上述目录均不具有 SlurmUser 的写权限,则不会生成核心文件。

    如果 slurmd 是使用 -D 选项启动的,则核心文件也将写入当前工作目录。如果 SlurmdLogFile 是绝对路径,则核心文件将写入该目录。否则,核心文件将写入 SlurmdSpoolDir,或者最后的选择是 "/var/tmp/"。
    如果上述目录均无法写入,则不会生成核心文件。

    对于 slurmstepd,核心文件将取决于故障发生的时间。如果它在特权阶段运行,则将位于上述 slurmd 守护进程描述的位置。如果它在非特权阶段运行,则将位于生成的作业的工作目录中。

    然而,在某些操作系统中,这可能会有所不同:

    • 例如,在 RHEL 中,该事件可能会被 abrt 守护进程捕获,并在定义的 abrt 配置转储位置生成(即 /var/spool/abrt)。

    通常,发行版需要进行更多调整,以便正确生成核心文件。

    slurmstepd 使用 setuid()(设置用户 ID)函数来提升特权。在某些系统和安全策略中,这可能导致核心文件无法生成。
    要允许在此类系统中生成核心文件,通常必须启用 suid_dumpable 内核参数:

    设置:
    /proc/sys/fs/suid_dumpable 为 2

    sysctl fs.suid_dumpable=2

    或在 sysctl.conf 中永久设置
    fs.suid_dumpable = 2

    值 2,"suidsafe",使任何通常不应转储的二进制文件仅对 root 可读。
    这允许最终用户删除此类转储,但无法直接访问。出于安全原因,在此模式下,核心转储不会相互覆盖或覆盖其他文件。
    此模式适合于管理员试图在正常环境中调试问题时使用。

    然后,您还必须将核心模式设置为绝对路径名:

    sysctl kernel.core_pattern=/tmp/core.%e.%p

    我们建议阅读您发行版的文档,以了解这些参数的配置。

    通常还需要配置系统核心限制,因为它可以设置为 0。

    $ grep core /etc/security/limits.conf
    #        - core - 限制核心文件大小(KB)
    *               hard    core            unlimited
    *               soft    core            unlimited
    

    在某些系统中,仅设置硬限制是不够的,您还必须设置软限制。

    此外,要在用户空间生成限制,可能需要在 slurm.conf 中设置 PropagateResourceLimits=CORE 参数。

    还要确保给予 SlurmUser 在核心位置目录中的适当权限。

    注意:在无盘节点上,取决于 core_pattern 或 /var/spool/abrt 是否指向类似 tmpfs 的内存文件空间,如果作业导致 OOM,则核心的生成可能会填满您机器的内存并使其挂起。因此,建议将核心转储发送到持久存储。小心多个节点将核心转储写入共享文件系统,因为这可能会显著影响它。

    其他例外:

    在 Centos 6 中,还需在文件 /etc/abrt/abrt-action-save-package-data.conf 中设置 "ProcessUnpackaged = yes"。

    在 RHEL6 中,还需在文件 rc.d/init.d/functions 中设置 "DAEMON_COREFILE_LIMIT=unlimited"。

    在启用 SELinux 的系统上,或在具有类似安全系统的发行版上,请确保它允许转储核心:

    $ getsebool allow_daemons_dump_core

    coredumpctl 也可以提供有价值的信息:

    $ coredumpctl info

    如何从核心文件获取回溯?
    如果您确实有导致核心文件生成的崩溃,您将希望获取该崩溃的回溯以发送给 SchedMD 进行评估。

    注意:核心文件必须由生成它们时使用的相同二进制文件进行分析。编译时的差异使得 SchedMD 几乎不可能使用来自不同系统的核心文件。您在提交支持请求时应始终发送回溯而不是核心文件。

    为了生成回溯,您必须使用 gdb,指定生成崩溃的 slurm* 二进制文件的路径,并指定核心文件的路径。以下是如何获取由 slurmctld 生成的核心文件的回溯的示例:

    gdb -ex 't a a bt full' -batch /path/to/slurmctld <core_file>
    

    您还可以使用 gdb 在没有核心文件的情况下生成回溯。如果您在启动时遇到崩溃并且由于某种原因没有获得核心文件,这可能会很有用。您希望从 gdb 内部启动二进制文件,等待其崩溃并生成回溯。以下是一个示例,使用 slurmctld 作为示例二进制文件:

    (gdb) /path/to/slurmctld
    (gdb) set print pretty
    (gdb) r -d
    (gdb) t a a bt full
    

    如果守护进程卡住或挂起,您可能还需要获取正在运行的守护进程的回溯。为此,您可以将 gdb 指向正在运行的二进制文件并让其生成回溯。以下是一个示例,再次使用 slurmctld 作为示例:

    gdb -ex 't a a bt' -batch -p $(pidof slurmctld)
    

    错误消息

    "无法解析 X 插件操作" 在守护进程启动时
    这意味着守护进程未找到插件中预期的符号。这通常发生在插件构建或安装不正确,或者配置文件告诉插件使用旧插件(例如来自 Slurm 的先前版本)。以详细模式重新启动守护进程以获取更多信息(例如 "slurmctld -Dvvvvv")。

    "凭证被重放" 在 SlurmdLogFile
    此错误表明 slurmd 守护进程无法及时响应来自 srun 命令的作业启动请求(几秒钟)。Srun 通过重新发送作业启动请求进行响应。当 slurmd 守护进程最终开始响应时,它处理两个请求。 第二个请求被拒绝,并且事件以 "凭证被重放" 错误记录。如果您检查 SlurmdLogFileSlurmctldLogFile,您应该会看到 slurmd 守护进程未响应的迹象。 多种因素可能导致此问题,包括

    • 无盘节点遇到网络问题
    • 非常慢的网络信息服务(NIS)
    • Prolog 脚本需要很长时间才能完成

    在 slurm.conf 中配置 MessageTimeout 为高于默认 10 秒的值。

    "无效的作业凭证"
    此错误表明 Slurm 的作业凭证文件在集群中不一致。集群中的所有节点必须具有与 Slurm 配置文件 slurm.conf 中定义的 JobCredPrivateKeyJobCredPublicKey 匹配的公钥和私钥。

    "任务启动失败,节点 ... 作业凭证被重放"
    此错误表明由 slurmctld 守护进程生成的作业凭证对应于 slurmd 守护进程已经撤销的作业。 slurmctld 守护进程根据配置的 FirstJobId 值选择作业 ID 值(默认值为 1),每个作业的值比前一个作业大 1。 在作业终止时,slurmctld 守护进程通知每个分配节点的 slurmd,所有与该作业关联的进程应终止。 slurmd 守护进程维护一个已终止作业的列表,以避免重放任务启动请求。 如果 slurmctld 守护进程被冷启动(使用 "-c" 选项或 "/etc/init.d/slurm startclean"),它将根据 FirstJobId 重新开始作业 ID 值。 如果 slurmd 也没有冷启动,它将拒绝认为已终止的作业的启动请求。 解决此问题的方法是在每次冷启动 slurmctld 守护进程时冷启动所有 slurmd 守护进程。

    "无法接受新连接:打开的文件太多"
    srun 命令会自动将其打开的文件限制增加到硬限制,以处理所有标准输入和输出连接到启动的任务。建议您在整个集群中将打开的文件硬限制设置为 8192。

    SlurmdDebug 未能在适当级别记录作业步骤信息
    这里涉及两个程序。一个是 slurmd,它是以所需的调试级别运行的持久守护进程。第二个程序是 slurmstepd,它执行用户作业,其调试级别由用户控制。使用 --debug=# 选项提交作业将导致在 SlurmdLogFile 中记录所需的详细信息以及程序的输出。

    "批处理 JobId=# 在批处理节点 <node> 中缺失(启动后未找到 BatchStartTime)"
    在作业分配的节点零上启动一个 shell 以执行提交的程序。每个计算节点上执行的 slurmd 守护进程将定期向 slurmctld 报告它正在执行的程序。如果预期某个节点(即作业分配的节点零)上正在运行批处理程序但未找到,则上述消息将被记录,并且作业将被取消。这通常与节点内存耗尽或其他无法恢复的关键故障有关。

    多实例 GPU 与 Slurm 和 PMIx 不兼容;GPU 显示为 "被另一个客户端使用"
    PMIx 使用 hwloc API 进行不同的目的,包括 OS 设备 功能,如查询 sysfs 文件夹(例如 /sys/class/net/sys/class/infiniband)以获取 Infiniband HCA 的名称。使用上述功能时,hwloc 默认查询 OpenCL 设备,这会在 /dev/nvidia* 文件上创建句柄。这些句柄由 slurmstepd 保持,并将在作业内部导致以下错误:

    $ nvidia-smi mig --id 1 --create-gpu-instance FOO,FOO --default-compute-instance
    无法使用配置 FOO 在 GPU 1 上创建 GPU 实例:被另一个客户端使用
    

    为了在 Slurm 和 PMIx 中使用多实例 GPU,您可以指示 hwloc 不查询 OpenCL 设备,通过为 slurmd 设置 HWLOC_COMPONENTS=-opencl 环境变量,即在 slurmd 的 systemd 单元文件中设置此变量。

    "srun: error: 无法接受连接:资源暂时不可用"
    在某些较大的集群上运行 SUSE Linux 时,用户的资源限制达到时已报告此问题。您可能需要增加锁定内存和堆栈大小的限制以解决此问题。

    "警告:处理时间非常长" 在 SlurmctldLogFile
    此错误表明某个操作花费了意外的很长时间才能完成,具体超过一秒钟。 将 SlurmctldDebug 配置参数的值设置为 debug2 或更高应能识别出哪些操作经历了长时间延迟。 此消息通常表示文件系统访问(写入状态信息或获取用户信息)存在长时间延迟。 另一种可能性是执行 slurmctld 守护进程的节点内存耗尽并正在分页。 尝试运行程序 top 以检查这种可能性。

    "重复条目" 导致 slurmdbd 失败
    此问题在 MySQL 中很少观察到,但在 MariaDB 中没有。 故障的根本原因似乎是达到自动增量字段的上限。 建议升级到 MariaDB。 如果不可能,则备份数据库,删除重复记录,并重新启动 slurmdbd 守护进程,如下所示。

    $ slurmdbd -Dvv
    ...
    slurmdbd: debug:  表 "cray_job_table" 已更改。正在更新...
    slurmdbd: error: mysql_query 失败:1062 重复条目 '2711-1478734628' 对于键 'id_job'
    ...
    
    $ mysqldump --single-transaction -u<user> -p<user> slurm_acct_db >/tmp/slurm_db_backup.sql
    
    $ mysql
    mysql> use slurm_acct_db;
    mysql> delete from cray_job_table where id_job='2711-1478734628';
    mysql> quit;
    再见
    

    如有必要,您可以编辑数据库转储并按如下所示重新创建数据库。

    $ mysql
    mysql> drop database slurm_acct_db;
    mysql> create database slurm_acct_db;
    mysql> quit;
    再见
    
    $ mysql -u<user> -p<user> </tmp/slurm_db_backup.sql
    

    "无法找到插件:serializer/json"
    Slurm 的几个部分已切换到使用我们的集中序列化代码。只有在执行需要它的函数时,才需要 JSON 或 YAML 插件。如果执行了其中一个函数,它将无法创建 JSON/YAML 输出,链接器将失败并显示以下错误:

    slurmctld: fatal: 无法找到插件:serializer/json
    

    在大多数情况下,这些是为 Slurm-20.02 之后添加的新功能所需的。 然而,随着每个版本的发布,我们添加了更多使用序列化插件的地方。由于列表在不断发展,我们不打算列出所有需要插件的命令,而是提供错误信息(如上所示)。要解决此问题,请确保 Slurm 已配置、编译并安装了相关的 JSON 或 YAML 库(或最好是两者)。可以明确请求这些库的配置:

    ./configure --with-json=PATH --with-yaml=PATH $@
    

    大多数发行版都包含使安装相对简单的包。请确保安装 'dev' 或 'devel' 包以及库包。我们还提供有关如何从源代码安装的明确说明: libyamllibjwt

    第三方集成

    Slurm 可以与 Globus 一起使用吗?
    是的。构建并安装 Slurm 的 Torque/PBS 命令包装器以及来自 Slurm 的 contribs 目录的 Perl API,并配置 Globus 使用这些 PBS 命令。 请注意,这两个软件包都有可用的 RPM,分别命名为 torqueperlapi

    如何配置 TotalView 以与 Slurm 一起操作?
    以下行也应添加到 TotalView 的全局 .tvdrc 文件中,以便与 Slurm 一起操作:

    # 启用调试服务器批量启动:已检查
    dset -set_as_default TV::bulk_launch_enabled true
    
    # 命令:
    # 从 TV 7X.1 开始,TV 支持 Slurm 和 %J。
    # 指定 --mem-per-cpu=0 以防 Slurm 配置了默认内存
    # 值,我们希望 TotalView 共享作业的内存限制,而不消耗作业的任何内存,以阻止其他作业步骤。
    dset -set_as_default TV::bulk_launch_string {srun --mem-per-cpu=0 -N%N -n%N -w`awk -F. 'BEGIN {ORS=","} {if (NR==%N) ORS=""; print $1}' %t1` -l --input=none %B/tvdsvr%K -callback_host %H -callback_ports %L -set_pws %P -verbosity %V -working_directory %D %F}
    
    # 临时文件 1 原型:
    # 主机行:
    # Slurm NodeNames 需要是未修饰的主机名。如果 %R 返回
    # 完全合格的主机名,请在此处列出 %t1 中的主机名,并在上述启动字符串中使用 awk 去除域名后缀。
    dset -set_as_default TV::bulk_launch_tmpfile1_host_lines {%R}
    

    最后修改于 2025 年 5 月 9 日