Slurm 集群调度系统深度解析与实战

深入剖析 Slurm 集群调度架构、作业提交、分区配置与调度策略,提供配置示例和常用命令速查表。

Slurm(Simple Linux Utility for Resource Management)是当今 HPC 领域最主流的集群资源调度与作业管理系统。它管理着全球 Top500 超算中超过半数以上的系统资源,从几节点的小型实验室集群到数万个节点的大型超算中心,Slurm 都提供了稳定、可扩展的调度能力。

Slurm 核心架构

+-----------------+     +-----------------+     +-----------------+
|   slurmctld     | <-> |   slurmdbd      | <-> |   slurmd        |
|   (控制器)      |     |   (记账数据库)  |     |   (计算节点)    |
|                 |     |                 |     |                 |
| 作业分配/调度   |     | 作业历史/用量   |     | 作业执行/监控   |
+-----------------+     +-----------------+     +-----------------+
        ^                     ^                       ^
        |                     |                       |
     sbatch/srun         sacct/sreport            ssh/mpi
  • slurmctld:中央控制器,负责任务队列管理、节点状态监控、作业调度决策。通常以主备模式部署。
  • slurmd:运行在每个计算节点上的守护进程,负责接收 slurmctld 指令、启停作业步(step)、收集资源使用数据。
  • slurmdbd:可选的记账数据库守护进程,将作业历史、资源用量记录至 MySQL/MariaDB,支撑 sacctsreport

作业提交方式

Slurm 提供三种核心提交方式,满足不同使用场景:

命令模式适用场景终端阻断
sbatch批处理长时间运行、无需交互否(后台)
srun实时运行MPI 并行程序、调试是(前台)
salloc交互式分配交互式调试、GPU 开发是(分配后进入 shell)

典型 sbatch 脚本示例:

#!/bin/bash
#SBATCH --job-name=mpi_stencil
#SBATCH --partition=cpu-std
#SBATCH --nodes=4
#SBATCH --ntasks-per-node=32
#SBATCH --cpus-per-task=1
#SBATCH --time=02:00:00
#SBATCH --output=%x-%j.out

module load openmpi/5.0
srun ./stencil_3d --grid 4096 --iter 10000

sbatch 支持参数覆盖:sbatch --nodelist=node[01-04] job.shsrun 是 MPI 作业的首选启动器,可自动处理 PMI/PMIx 进程映射。

分区与队列配置

slurm.conf 中的 Partition 定义了资源分组策略,类比云平台的队列概念:

PartitionName=cpu-std Nodes=cpu[001-128] Default=YES MaxTime=48:00:00 State=UP
PartitionName=cpu-long Nodes=cpu[129-160] MaxTime=168:00:00 Priority=10
PartitionName=gpu-a100 Nodes=gpu[001-032] MaxTime=24:00:00 Gres=gpu:a100:8
PartitionName=debug Nodes=cpu[001-004] MaxTime=00:30:00 MaxNodes=2 PriorityTier=100

关键配置项说明:

配置项作用
Default用户未指定分区时的默认队列
Priority / PriorityTier数值越高,该分区获得调度优先权
MaxTime / MaxNodes防止单个作业过度占用资源
Gres声明通用资源(GPU、FPGA、NVMe 等)
OverSubscribe控制节点/CPU 是否允许超配

调度策略详解

Slurm 调度器(sched/backfillsched/builtin)的核心目标是在满足资源约束的前提下最大化吞吐量与利用率。

Backfill 回填调度

Backfill 是生产环境最常用的策略。其工作逻辑如下:

队列状态: [J1: 需 100 节点, 2 小时] [J2: 需 10 节点, 1 小时] [J3: 需 50 节点, 0.5 小时]
当前空闲: 60 节点

步骤 1: J1 优先级最高,预留未来 100 节点,预计开始时间 T+2h
步骤 2: Backfill 扫描 J2、J3...
        J3 运行 0.5h 后释放,不影响 J1 预留 => 允许 J3 立即运行
        J2 运行 1h 后释放,仍不影响 J1 预留 => 允许 J2 立即运行
结果: J2 和 J3 被"回填",在 J1 等待期间充分利用空闲资源

配置开启 Backfill:

SchedulerType=sched/backfill
SelectType=select/cons_tres
SelectTypeParameters=CR_Core_MEMORY

CR_Core_MEMORY 表示按 Core 和 Memory 作为可分配资源粒度,避免整节点浪费。

Gang Scheduling 分时调度

当资源不足但作业要求低延迟响应时,Gang Scheduling 允许多个作业共享同一组 CPU/GPU 时间片。Slurm 通过 PreemptMode=SUSPEND,GANG 配合 OverSubscribe=FORCE 实现。

⚠️ 注意:Gang 调度对 MPI 同步密集型应用可能造成性能抖动,推荐仅用于开发调试或 I/O 密集型负载。

QoS 与优先级系统

QoS(Quality of Service)为不同用户/项目提供差异化的资源承诺:

# 创建 QoS
sacctmgr add qos gold flags=OverPartQOS priority=100 \
  MaxWall=72:00:00 MaxTRESPU=cpu=256,gres/gpu=8 \
  GrpTRES=cpu=2048 GrpJobs=50

# 绑定用户至 QoS
sacctmgr modify user where name=alice set qos=gold

优先级计算公式(PriorityType=priority/multifactor):

Priority = (Age_weight * Job_Age / Max_Age)
         + (JobSize_weight * Job_Size / Max_Size)
         + (Partition_weight * Partition_Factor)
         + (QOS_weight * QOS_Factor)
         + (FairShare_weight * FairShare_Factor)

Fair-Share 避免单一用户长期垄断资源,其衰减窗口可用 PriorityDecayHalfLife 调节。

资源预留与抢占

对于 deadline 敏感型作业,可提前锁定资源:

# 预留 64 节点未来 2 小时,供用户 bob 使用
scontrol create reservation=urgent_res \
  starttime=now+2hours duration=4hours \
  nodes=64 flags=maint,ignore_jobs users=bob

# 查看预留
scontrol show reservation=urgent_res

抢占策略(PreemptMode=CANCELREQUEUE)允许高优先级作业踢走低优先级正在运行的作业。REQUEUE 模式会重新排队被抢占作业,适合容错良好的 checkpoint/restart 应用。

常用命令速查表

操作命令
提交批处理作业sbatch job.sh
交互式运行命令srun --pty /bin/bash
查看队列squeue -u $USER --format="%.18i %.9P %.8j %.8u %.2t %.10M %.6D %R"
取消作业scancel <jobid>
查看作业详情scontrol show job <jobid>
查看节点状态sinfo -N -o "%N %.6D %.10T %.4c %.8z %.6m %.10G %E"
查看历史作业sacct -j <jobid> --format=JobID,JobName,Partition,State,Elapsed,MaxRSS
查看用量报告sreport cluster utilization
调整作业时间scontrol update job <jobid> timelimit=04:00:00
挂起/恢复作业scontrol hold <jobid> / scontrol release <jobid>

生产环境最佳实践

  1. 合理设置 DefMemPerCPU:避免作业因内存 OOM 被 Kill,同时防止用户申请整节点却只用一个核心。
  2. 启用 Prolog/Epilog 脚本:在作业启动前后执行健康检查、环境准备、日志归档。
  3. 配置 JobAcctGatherType=jobacct_gather/cgroup:使用 cgroup 精确采集 CPU、内存、I/O 用量。
  4. 定期 slurmctld checkpointSlurmctldParameters=archive_jobs 确保控制器故障时可快速恢复状态。
  5. Gres 资源绑定:GPU 作业务必使用 --gpus-per-task--gres=gpu:4,防止进程漂移导致数据局部性丧失。

Slurm 的灵活配置使其既能服务国家级超算中心,也能适配企业内部的 AI 训练集群。理解其核心调度机制,是 HPC 系统管理员和重度用户的必修课。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「hpc」更多文章

  1. Roofline 性能模型:判定性能瓶颈与优化方向
  2. ROCm HIP GPU 编程实战
  3. PETSc 科学计算库实战指南