人们很容易把 Slurm 误认成一条让程序排队等待的命令:提交脚本,在 squeue 中看到 PENDING,眼前仿佛只是一套语法格外复杂的队列。它真正交付的是一份更有用的承诺:在有限时间内,某一组 CPU、内存、GPU 和节点归一个作业使用。随后,Slurm 会把这份承诺与其中启动的程序分开管理。
这种分离让 Slurm 同时胜任集群资源管理器和作业调度器。它分配资源,让工作可以在资源上启动并接受监控,还要裁决相互冲突的请求。因此,理解这个项目最清楚的起点是一组名词——节点、分区、作业和作业步骤——以及维持它们各自含义的运转体系。[1]
上方照片拍摄的是橡树岭国家实验室的 Frontier;其用户指南明确说明,这套系统采用 Slurm 作为批处理调度系统。[7] 这幅图并非泛指数据中心的背景画面。一排机柜能够供应庞大的计算能力,却仍不足以成为多人共享的科研服务。必须有人决定怎样的资源组合才是有效请求、谁有权取得资源、使用权何时生效、工作如何进入已经分配的机器,以及结束后要留下哪些记录。Slurm 正是让这些决策可以接受检查的开源控制平面。
四个名词把硬件变成共享服务
节点是 Slurm 的基本计算资源,通常对应一台列明资源清单的 Linux 机器。不同节点的处理器数量、内存、加速器、本地存储或功能特征可以各不相同。Slurm 保留这些差异,并为管理员和用户提供请求相应资源的共同词汇。
分区把节点归入一个逻辑集合。不同分区可以重叠,因此它们并不等同于贴上不同标签的物理机架通道。每个分区都可以附带策略,例如允许使用的用户、默认与最长运行时间,以及作业规模上限。同一个 GPU 节点可以同时出现在通用分区和受限的项目分区中。把分区称为队列很方便,却只涵盖了一部分含义;分区把符合条件的硬件池与一套准入策略连在一起。[1][5]
作业指资源分配本身,也就是在有限时间内取得资源使用权。作业步骤则是在这份使用权之内启动的一组任务。一个作业可以只有一个占满全部已分配节点的步骤,也可以让多个步骤依次复用同一份资源,或由并发步骤分用资源。NERSC 的运维文档给出了具体区别:sbatch 提交脚本,留待之后执行;srun 则可以在 sbatch 或 salloc 取得的资源内创建实时步骤。[6]
有了这些名词,便能理解等待中的作业为何不只是“排在下一位”。一项请求有自己的完整规格,例如四个节点、每个节点八块 GPU、40 分钟、某种指定特征、一个账户,以及规则允许该请求进入的分区。稍后到达的小作业可以先找到空位,同时不占用较早作业预计开始时所需的资源。高优先级请求也会等待,因为当前空闲节点未必能满足它的完整规格。
控制器授予资源,节点启动任务
Slurm 的守护进程分工与上述概念划分彼此对应。中央 slurmctld 保存作业、节点和分区的权威状态,并决定资源分配。备用控制器可以利用共享的已保存状态接管服务。每个计算节点都运行 slurmd,负责接收获准运行的工作,并在本机管理任务。[1][5]
启动一个步骤时,控制器不会在每个节点上逐一派生所有进程。srun 向 slurmctld 请求创建步骤;控制器返回一份描述已授予资源的签名凭据;srun 把启动请求和凭据转交给 slurmd;参与运行的每个节点再为该步骤启动一个 slurmstepd。步骤守护进程会先准备环境、I/O、进程跟踪,以及 MPI 或网络插件所需的工作,随后执行任务。节点本地的启动流程避开中央控制器的关键执行路径,使控制器可以继续接纳并调度集群中的其他请求。[2]
这条分界也让各类故障有了更准确的名称。作业会因控制器无法安置其请求而停留在等待状态。已经分配的节点会在执行期间发生故障。某个步骤会遇到任务布局错误,而原有资源分配仍然有效。任务可以成功启动,同时记账数据有所延迟。与笼统地说“集群坏了”相比,“节点已进入 DRAIN 状态”“步骤凭据遭拒”或“请求无法装入这个分区”更有助于定位问题。
脚本请求一份承诺,srun 使用这份承诺
下面这份小型 GPU 批处理脚本展示了两个层级:
#!/bin/bash
#SBATCH --job-name=solver
#SBATCH --nodes=2
#SBATCH --time=00:20:00
#SBATCH --partition=gpu
#SBATCH --gpus-per-node=4
srun --ntasks=8 --gpus-per-task=1 ./solver input.dat
这些 #SBATCH 行描述资源分配:两个符合条件的节点、20 分钟的运行上限、一个由站点定义的分区,以及每个节点四块 GPU。sbatch 发送请求并返回作业 ID。资源分配开始生效后,最后一行才会创建一个包含八项任务的步骤。这段示例有意保留其站点相关性,照搬到别处无法保证运行——分区名称、账户要求、GPU 选项和默认值都由站点决定——但资源分配与作业步骤的区别适用于各种 Slurm 安装。[6]
salloc 为交互式工作取得资源。srun 在现有资源分配之外运行时,可以一次完成资源请求和工作启动;在资源分配之内运行时,它负责启动一个步骤。squeue 显示等待中和运行中的工作。配置记账功能后,sacct 用于回看历史记录。这些工具是观察同一状态机的不同窗口,各自都要遵循其中的资源规则。
由此可以厘清两种常见误解。第一,取得资源分配时,各个并行进程还没有全部安排妥当;作业步骤仍需确定任务布局。第二,作业内的 srun 通常会使用现有承诺中的部分或全部资源,它不会自动取得第二组节点。多个步骤共享一份资源分配时,它们申请的 CPU、内存和 GPU 必须能够同时容纳,正如最初的作业请求必须能够装入集群一样。
TRES 为不同种类的资源建立同一套记账语法
对于混合型集群,单看 CPU 数量远远不够。Slurm 把范围更广的记账单位称为 Trackable RESources(可跟踪资源),简称 TRES。当前的 TRES 类型包括 CPU、内存、节点、能源、许可证、文件系统和 GRES;GRES 是 GPU 等通用资源所属的类别。管理员可以把资源加入 AccountingStorageTRES,用 PriorityWeightTRES 为请求的资源设定优先级权重,还可以通过各分区专属的 TRESBillingWeights,把不同类型的资源消耗换算成计费量。[3]
这套词汇把三个经常分散在不同系统中的问题连在一起:
- 作业能否得到安置? 选择插件必须找到可消耗资源满足请求的节点。若要在节点内共享处理器、内存和其他资源,管理员指南推荐使用
select/cons_tres。[5] - 作业使用或预留了什么? 记账记录可以保存 CPU、内存、GPU 和其他已经声明的资源项目,让一次运行的记录涵盖比用时更多的信息。[3]
- 资源使用应当怎样影响策略? 站点可以针对同一套资源词汇应用资源限制、公平份额计算或优先级权重。[3]
TRES 不会让所有加速器变得可以互换。作业仍可指定 GPU 类型、功能特征、拓扑或站点特有的约束,资源清单也必须符合节点的实际情况。这个抽象层的价值来自请求、安置决策和记账记录之间的连续对应;它的目标并非把异构硬件变成完全相同的 token。
优先级决定次序,回填调度寻找空位
调度同样包含两份契约。优先级为符合条件的作业排序。具体因素取决于配置,可以包括等待时间、规模、关联关系、公平份额、分区、服务质量和所请求的资源。[5] 随后,调度器依据集群真实的可用状况和拓扑尝试安置作业。
现行调度指南记录了两种调度器插件。sched/builtin 尝试严格遵循优先级次序。默认的回填插件只会在较低优先级作业不延误较高优先级作业预计开始时间的前提下,让前者先行运行。因此,如实填写最长运行时间属于调度所需的运行数据。回填调度要依据结束时间估计,找出计划中可以安全利用的空档。[4]
同一份指南也展示了看似静止的队列背后可以有多少工作。事件触发式调度默认考察 100 个作业;主循环记录的默认间隔为 60 秒;回填调度记录的默认间隔为 30 秒。这些都是可以调整的默认值,并非性能承诺。在繁忙的 Slurm 安装中,请求量、作业数组规模、拓扑检查、控制器 RPC 流量和站点策略共同决定这些数值是否合适。[4]
对用户而言,实际影响很清楚。把最长运行时间大幅报高,会减少作业参与回填调度的机会。时间报得过短,则会让作业在有效输出安全写入检查点之前遭到终止。单看队列位置无法说明这种取舍;等待原因、请求规格、预计开始时间和应用程序的检查点行为能提供更充分的依据。
真正的难点在于履行资源承诺
Slurm 可以自行托管,但开源软件的控制平面仍需人工运维。管理员指南要求集群使用统一的用户和用户组命名空间、组件之间经过认证的通信、一致的配置、可写的运行时路径,以及持久保存的控制器状态。采用 MUNGE 认证时,各节点需要使用同一密钥并保持时钟同步。Slurm 也不会代替运维人员创建日志、PID 文件、spool 和状态文件所需的父目录。[5]
StateSaveLocation 尤其重要。控制器重启或故障切换时,它能保存排队中、运行中和刚刚完成的作业状态。SchedMD 建议采用低延迟存储;部署备用控制器时,则建议使用共享文件系统。指南还警告,控制器启动时若无法访问这些状态,排队中和运行中的作业会被取消。[5] 因此,增加第二个主机名还不足以达到高可用要求。两台控制器都必须看到可信的状态路径,恢复流程也必须经过测试。
隔离是另一条明确的界线。Slurm 会认证自身消息并跟踪由它启动的工作,但其本身不会阻止用户直接登录已经分配的计算节点。要求严格访问隔离的站点必须增加 PAM 模块或同类控制,并确定怎样清理由 Slurm 监管范围之外启动的进程。[5] 通过 slurmdbd 记账、数据库保留策略、cgroup 强制执行、prolog 和 epilog 钩子、监控及升级演练都属于运维选择,安装 slurmctld 并不会自动完成这些工作。
哪些组织适合采用 Slurm
当多个用户或服务争用一组 Linux 计算资源,而组织需要明确回答四个问题时,Slurm 很合适:请求了什么、授予了什么、授权范围内运行了什么,以及此次使用应当怎样影响今后的访问。小型科研集群与 Frontier 都符合这项描述。当工作天然适合批处理、运行时间可以设定上限、并行启动十分重要,并且 CPU、GPU、内存或许可证需要统筹调度时,Slurm 尤其有吸引力。
一台只供一名可信用户使用的工作站,通常用不到这套控制平面。Slurm 也不能替代存储架构、可复现的软件环境、工作流重试、应用程序检查点或可观测性。它可以启动容器,却不会判断镜像在科研意义上是否有效;可以预留 GPU,却不会让程序自动提高利用效率;也会在最长运行时间到达时终止作业,却无法生成应用程序从未写出的检查点。
一套审慎的试点环境可以保持很小:一台控制器及其状态备份方案、少量计算节点、一个分区、一致的身份信息与认证,再加上一项已知可用的 srun -N1 /bin/hostname 测试。把公平份额用于策略之前,应先加入记账功能。确认 CPU 和内存安置可靠之后,再加入 GPU 资源清单。向用户承诺集群服务可靠之前,还应演练节点 DRAIN、控制器重启、作业取消、时限信号和已完成作业报告。[5]
Slurm 的成就并非维护一条很长的队列。它把共享硬件变成可以审查的资源承诺,同时让每份承诺与其中实际执行的工作保持分离。当节点、分区、作业和步骤不再混为一谈,命令会更容易理解,各类故障也有了可以落实到运维操作的名称。
来源
- SchedMD,《Slurm Workload Manager — Quick Start User Guide》——项目用途、守护进程概览,以及节点、分区、作业和作业步骤的定义。
- SchedMD,《Job Launch Design Guide》——资源分配、签名步骤凭据、
slurmd扇出、slurmstepd、任务启动和终止流程。 - SchedMD,《Trackable RESources (TRES)》——资源类型、记账配置、优先级权重和计费权重。
- SchedMD,《Scheduling Configuration Guide》——事件调度、调度器插件、回填行为、时间默认值和对最长运行时间的依赖。
- SchedMD,《Quick Start Administrator Guide》——控制器与节点角色、认证、高可用、状态保存、配置、资源选择、记账和访问控制界线。
- National Energy Research Scientific Computing Center,《Basics of Running Jobs》——来自独立生产站点的说明,涵盖
sbatch、salloc、srun、资源分配和作业步骤。 - Oak Ridge Leadership Computing Facility,《Frontier User Guide》——生产系统文档,说明 Frontier 使用 Slurm 作为调度器,并展示资源分配与启动流程。
- Oak Ridge Leadership Computing Facility,《Frontier Supercomputer (1)》——文章所用橡树岭国家实验室实景照片的来源页面,图片经 Wikimedia Commons 获取。