4. SLURM 基本配置:slurm.conf 关键参数与实战

聊到 SLURM,最绕不开的就是 slurm.conf。我个人习惯,接手一个新集群,第一件事就是翻这个文件。它决定了集群的“骨架”和“规则”。

说白了,SLURM 的所有行为都靠这个文件驱动。写对了,集群就稳了一半。写错了,排查起来够你喝一壶的。今天咱们就挑几个最关键的参数来拆解一下。

4.1 核心配置文件 slurm.conf 的位置与骨架

这个文件通常放在 /etc/slurm/ 或 /etc/slurm-llnl/ 下。你安装好 SLURM 后,第一步就是配置它。

它的骨架大概长这样:

#
# slurm.conf (Sample)
#
ClusterName=mycluster
ControlMachine=master01
ControlAddr=192.168.1.10
# 其他全局参数...

# 节点定义
NodeName=node01 NodeAddr=192.168.1.11 CPUs=16 RealMemory=64000
NodeName=node02 NodeAddr=192.168.1.12 CPUs=16 RealMemory=64000
# 其他节点...

# 分区定义
PartitionName=normal Nodes=node[01-08] Default=YES MaxTime=INFINITE State=UP
PartitionName=debug Nodes=node[01-02] Default=NO MaxTime=1:00:00 State=UP

嗯,这里要注意,参数的顺序其实无所谓,但逻辑一定要清晰。我见过有人把 ControlMachine 写成了计算节点的名字,结果整个集群都找不到老大。

4.2 关键参数详解

咱们逐个拆解,重点讲讲我踩过坑的几个。

4.2.1 ControlMachine 与 ControlAddr

这是 SLURM 的“大脑”。ControlMachine 指定运行 slurmctld 服务的主机名。ControlAddr 则是它的 IP 地址。

  • ControlMachine:必填。所有计算节点和服务进程都知道该找谁汇报。
  • ControlAddr:可选,但强烈建议填写。如果你有 DNS 解析或 hosts 文件,可以省略。但为了稳定,我会直接写 IP。
我曾经遇到过: 有一次机房 DNS 挂了,所有节点都找不到控制节点。从那以后,我习惯性把 ControlAddr 写死成 IP,避免这种“低级”灾难。

4.2.2 NodeName 与节点定义

每个计算节点都必须在这里注册。你想想看,SLURM 怎么知道你有哪些机器可以用呢?

参数格式:

NodeName=主机名 NodeAddr=IP地址 CPUs=核心数 RealMemory=内存MB State=状态

这里有几点要注意:

  • NodeName:主机名,必须与 hostname 一致,或者能被 hosts 文件解析。
  • NodeAddr:计算节点的管理网 IP。
  • CPUs:节点的 CPU 核心数。SLURM 靠它分配任务。
  • RealMemory:节点的物理内存(MB)。SLURM 用它判断内存是否足够。
  • State:初始状态,通常是 UNKNOWN,SLURM 启动后会根据实际通信结果更新。

举个例子:

NodeName=compute01 NodeAddr=10.0.0.1 CPUs=32 RealMemory=128000 State=UNKNOWN
NodeName=compute02 NodeAddr=10.0.0.2 CPUs=64 RealMemory=256000 State=UNKNOWN

注意,如果你的节点数量很多,比如 100 台,可以用简写模式:

NodeName=compute[01-100] NodeAddr=10.0.0.[1-100] CPUs=32 RealMemory=128000

这个正则写法能省很多事。不过,要确保 IP 地址和主机名能够一一对应。

4.2.3 PartitionName 与分区定义

分区,就是“队列”。你把节点划分成不同的逻辑组,用户提交作业时,指定分区名即可。

PartitionName=队列名 Nodes=节点列表 Default=是否默认 MaxTime=最大运行时间 State=状态
  • PartitionName:队列名称,比如 normal、gpu。
  • Nodes:属于该队列的节点。可以是 node[01-10] 或者 node01,node02。
  • Default:YES 或 NO。如果你不指定 --partition,作业就会被投到默认分区。
  • MaxTime:最大运行时间。格式为 DAYS-HOURS:MINUTES:SECONDS。比如 3-00:00:00 表示 3 天。
我建议: 给不同的工作负载设计不同的分区。比如 debug 分区 MaxTime=1:00:00,快速测试用;long 分区可以设置 MaxTime=14-00:00:00,跑长任务。这样可以防止长作业把测试节点占满。

实际例子:

PartitionName=normal Nodes=compute[01-08] Default=YES MaxTime=INFINITE State=UP
PartitionName=highmem Nodes=compute[09-10] Default=NO MaxTime=7-00:00:00 State=UP

4.2.4 DefMemPerCPU 与 DefMemPerNode

这是个很重要的资源限制参数。它定义了用户不指定内存时,默认每个 CPU 核心或每个节点能分配到多少内存。

  • DefMemPerCPU:每个 CPU 分配的默认内存(MB)。
  • DefMemPerNode:每个节点分配的默认内存(MB)。

为什么要专门配置这个参数?

我遇到过这种情况:用户提交作业时不指定 --mem,结果 SLURM 默认认为作业只需要很少的内存,于是把很多作业塞到同一个节点。最后内存 OOM,机器 hang 了。

所以,我建议设置一个合理的默认值。比如:

DefMemPerCPU=2048
# 或者
DefMemPerNode=32000

这样一来,哪怕用户忘写内存申请,作业也有基本保障。不过要注意,这两个参数不能同时使用。SLURM 会检查冲突。我通常选择 DefMemPerCPU,因为更灵活。

4.2.5 MaxMemPerLimit 与 MaxMemPerNode

有默认值,就有上限。可以防止用户内存申请过大,把整台机器的资源都抢走。

MaxMemPerLimit=64000   # 每个作业最多申请 64GB 内存
MaxMemPerNode=128000   # 每个节点最多 128GB

你想想看,如果和 RealMemory 配合使用,就能精确控制每个作业的资源范围了。

4.3 实战检查步骤

配置文件写好后,不是直接重启就完事了。我建议按以下步骤验证:

  1. 语法检查:slurmctld -t。它会告诉你 slurm.conf 有没有语法错误。
  2. 模拟加载:slurmctld -C。它会模拟加载配置,并输出集群信息,检查节点和分区是否定义正确。
  3. 重启核心服务:systemctl restart slurmctld。在主控节点执行。
  4. 同步给所有节点:记得把 slurm.conf 复制到所有计算节点的 /etc/slurm/ 目录下,然后重启 slurmd。
  5. 检查状态:sinfo 看节点状态,scontrol show node 看详细配置。

来看看具体的命令输出示例:

# 检查配置文件
$ slurmctld -t
slurmctld: slurm.conf syntax OK

# 能看到节点只有 16 个 CPU?那是因为我定义的就是 16
$ scontrol show node node01
NodeName=node01 Arch=x86_64 CoresPerSocket=8
   CPUAlloc=0 CPUTot=16 CPULoad=0.01
   RealMemory=64000 AllocMem=0 FreeMem=52345
   State=IDLE

嗯,看到 State=IDLE,说明配置生效了。如果出现 DOWN 或 DRAIN,就要检查网络或 slurmd 服务了。

4.4 一张图看懂核心配置

为了让你更直观地理解这些配置之间的关系,我画了一张概念图。

SLURM 核心配置概念图 slurm.conf 核心配置关系 slurm.conf 配置文件 ControlMachine 控制节点/集群大脑 NodeName / Nodes 计算节点定义与归属 PartitionName 队列/分区逻辑分组 DefMemPerCPU 默认内存 / 资源限制 sinfo / scontrol 状态检查与验证 核心组件:ControlMachine (主控) → Nodes (计算) → Partitions (队列) → 资源限制 → 状态验证

从这张图可以看出来,slurm.conf 就像是一个指挥中心。它先定义好“大脑”(ControlMachine),然后是“手脚”(Nodes),接着把“手脚”分组到不同“生产部门”(Partitions),最后给每个人设定“饭量”(资源限制)。

4.5 避坑与经验

  • 节点名称冲突:我踩过坑。节点 NodeName 和 NodeAddr 写了不同的机器,但主机名解析时指向同一台。SLURM 会识别失败,报错 Node not responding。
  • RealMemory vs 实际内存:RealMemory 要填写物理内存总量。SLURM 用它来计算剩余资源。填少了任务可能被拒,填多了容易 OOM。
  • 分区状态:分区 State=UP 表示可用。如果设置成 DOWN,这个分区就暂时不接活了,适合维护的时候用。
  • 配置文件同步:修改 slurm.conf 后,必须同步到所有节点。我见过有人只改了主控,忘了计算节点,导致作业跑在“旧配置”上,内存限制没生效。
一句话总结: 配置文件是 SLURM 的灵魂。花时间搞懂它,绝对值得。