Slurm 集群内存管理与限制配置

Slurm 集群内存管理与限制配置

目录

  1. 问题背景
  2. [Slurm 内存管理机制详解](#Slurm 内存管理机制详解)
  3. 配置参数深度解析
  4. 完整配置方案
  5. 配置原理说明
  6. 实施步骤详解
  7. 测试与验证
  8. 常见问题排查

问题背景

典型场景

在多用户共享的 Slurm 集群中,经常出现以下问题:

  • 问题1:资源独占

    用户提交单个作业申请整个节点的全部内存(如 512GB),导致该节点无法被其他作业使用,即使该作业实际只使用了部分内存(如 200GB)。

  • 问题2:内存分配不生效

    管理员配置了"按 CPU 核心数自动分配内存",但用户使用 sallocsbatch 时,系统并未按预期分配,可能分配了整个节点的内存或使用了错误的默认值。

期望目标

  1. 限制单个作业最大内存:例如,512GB 节点最多允许单作业申请 80%(约 410GB),为其他作业预留空间
  2. 自动按 CPU 核心分配内存:用户申请 N 个 CPU 时,自动分配 N×X GB 内存(如 4GB/核)
  3. 强制执行内存限制:作业超出申请内存时,系统自动终止该作业,保护节点稳定性

Slurm 内存管理机制详解

1. 调度器类型(SelectType)

Slurm 提供多种资源选择插件,常用的有:

插件名称 说明 适用场景
select/linear 节点级别调度,分配整个节点 小型集群,作业独占节点
select/cons_res 可消耗资源调度(CPU/内存) 通用场景(较旧)
select/cons_tres 可跟踪可消耗资源调度(推荐) 现代集群,精细资源管理

当前配置:

conf 复制代码
SelectType=select/cons_tres

✅ 这是正确的,支持细粒度的 CPU、内存、GPU 等资源管理。


2. 调度参数(SelectTypeParameters)

此参数决定哪些资源是"可消耗资源"(consumable resource)。

参数值 含义 内存管理
CR_CPU 仅 CPU 是可消耗资源 ❌ 内存不受调度管理
CR_Core 仅核心是可消耗资源 ❌ 内存不受调度管理
CR_CPU_Memory CPU 和内存都是可消耗资源 ✅ 内存纳入调度
CR_Core_Memory 核心和内存都是可消耗资源(推荐) ✅ 内存纳入调度

当前配置:

conf 复制代码
SelectTypeParameters=CR_Core

问题: 只有核心被管理,内存不受调度器控制。

影响:

  • Slurm 不会跟踪节点内存使用情况
  • 用户可以申请超过节点物理内存的量
  • 多个作业可能导致节点内存超用(OOM)

修改为:

conf 复制代码
SelectTypeParameters=CR_Core_Memory

这样,Slurm 会同时跟踪核心和内存的使用情况,确保:

  • 节点内存不会被超额分配
  • 调度器根据内存可用性调度作业
  • 多个作业可以共享同一节点(如果内存足够)

3. 内存限制参数详解

DefMemPerCPU(默认每 CPU 内存)

作用: 当用户不显式指定 --mem--mem-per-cpu 时,每个 CPU 核心的默认内存分配量。

示例:

conf 复制代码
DefMemPerCPU=4096  # 每个 CPU 默认 4GB

用户行为:

bash 复制代码
# 用户执行:
salloc -n 8

# 系统自动分配:8 × 4GB = 32GB 内存

单位: MB(兆字节)

MaxMemPerCPU(每 CPU 最大内存)

作用: 限制用户通过 --mem-per-cpu 单个 CPU 可以申请的最大内存,防止用户绕过限制。

示例:

conf 复制代码
MaxMemPerCPU=16384  # 每个 CPU 最多 16GB

防止的行为:

bash 复制代码
# 用户尝试:
salloc -n 1 --mem-per-cpu=100G

# 系统拒绝:超过 MaxMemPerCPU=16G 的限制
MaxMemPerNode(单作业节点最大内存)

作用: 限制单个作业在单个节点上可以申请的最大总内存。

示例:

conf 复制代码
# 节点有 512GB 物理内存,限制单作业最多 80% = 409.6GB
MaxMemPerNode=419840  # 单位:MB

效果:

bash 复制代码
# 用户尝试:
sbatch --mem=450G job.sh

# 系统拒绝:超过分区的 MaxMemPerNode=420000MB (约410GB) 限制

计算公式:

复制代码
MaxMemPerNode = 节点物理内存 × 80% × 1024
例如:512GB × 0.8 × 1024 = 419840 MB

4. Cgroup 强制执行机制

仅在配置文件中设置内存限制是不够的,因为:

  • 配置文件只影响调度决策(作业能否提交)
  • 不能防止作业运行时超用内存

解决方案: 使用 Linux Cgroup(Control Groups)在操作系统层面强制限制。

ConstrainRAMSpace(限制内存空间)

作用: 启用后,Slurm 会为每个作业创建独立的 Cgroup,物理限制其内存使用。

conf 复制代码
ConstrainRAMSpace=yes

效果:

  • 作业申请 100GB,只能使用最多 100GB
  • 超用时,内核 OOM Killer 会终止作业进程
AllowedRAMSpace(允许的内存空间百分比)

作用: 允许作业使用申请内存的百分比(包含缓冲)。

conf 复制代码
AllowedRAMSpace=100

值说明:

  • 100:严格限制,只能使用申请的 100%
  • 105:允许 5% 缓冲,用于系统开销
  • 90:仅允许使用 90%(一般不推荐)
ConstrainSwapSpace(限制交换空间)

作用: 防止作业使用 Swap 空间,确保性能稳定。

conf 复制代码
ConstrainSwapSpace=yes

效果:

  • 作业不能使用 Swap
  • 超内存立即被杀死,而非性能下降后慢慢失败

配置参数深度解析

为什么 sallocsbatch 行为不同?

sbatch 的默认行为
bash 复制代码
sbatch job.sh
  • 会使用 DefMemPerCPU 的默认值
  • 按申请的 CPU 数自动分配内存
salloc 的默认行为
bash 复制代码
salloc -n 4
  • 在某些配置下,可能请求整个节点
  • 或者忽略 DefMemPerCPU,导致分配不符合预期

原因:
salloc 是交互式分配,某些 Slurm 版本对其默认行为处理不一致。

解决方案:

  1. 修改 SelectTypeParameters=CR_Core_Memory(核心配置)
  2. 设置 DefMemPerCPU 强制默认值
  3. 用户养成显式指定 --mem--mem-per-cpu 的习惯

节点内存配置:RealMemory

在节点定义中,必须正确设置 RealMemory

conf 复制代码
NodeName=cn02 RealMemory=515072 Sockets=2 ThreadsPerCore=2 CoresPerSocket=32 CPUs=128

RealMemory 的含义:

  • 节点可用于作业的物理内存(MB)
  • 不是节点的总内存(需扣除操作系统和系统服务占用)

如何计算:

bash 复制代码
# 在节点上查看实际可用内存
ssh cn02 "free -m | grep Mem"

# 输出示例:
# Mem:  515072  10240  504832  ...
#       ^^^^^^
#       这是可用内存

建议:

RealMemory 设置为物理内存的 95-98%,例如:

  • 512GB 物理内存 → RealMemory=515072 (503GB)
  • 256GB 物理内存 → RealMemory=257024 (251GB)

完整配置方案

配置目标

节点 物理内存 RealMemory 80% 限制 MaxMemPerNode (MB)
cn01-03 256GB 257024MB 205GB 210000
cn02-05, cn10 512GB 515072MB 412GB 420000
cn06, cn08 64GB 63488MB 50GB 51200
cn07 192GB 191488MB 152GB 155000
cn09 256GB 257024MB 205GB 210000

全局配置:DefMemPerCPU

conf 复制代码
# 默认每个 CPU 4GB
DefMemPerCPU=4096

# 单个 CPU 最多 16GB(防止 --mem-per-cpu=100G)
MaxMemPerCPU=16384

用户体验:

  • 申请 32 核:自动分配 128GB 内存
  • 申请 64 核:自动分配 256GB 内存
  • 显式指定:salloc -n 32 --mem=200G(覆盖默认值)

实施步骤详解

Step 1: 备份现有配置

为什么要备份?

  • 配置错误可能导致集群无法调度作业
  • 出现问题时可以快速回滚
bash 复制代码
cd /etc/slurm
cp slurm.conf slurm.conf.backup.$(date +%Y%m%d)
cp cgroup.conf cgroup.conf.backup.$(date +%Y%m%d)

验证备份:

bash 复制代码
ls -lh slurm.conf.backup.*

Step 2: 修改 slurm.conf(管理节点)

修改 2.1:调度参数

位置: 第 66 行附近

原配置:

conf 复制代码
SelectTypeParameters=CR_Core

修改为:

conf 复制代码
SelectTypeParameters=CR_Core_Memory

原理说明:

  • CR_Core:只管理 CPU 核心,内存不受 Slurm 跟踪
  • CR_Core_Memory:同时管理核心和内存,内存成为可调度资源

影响:

  • Slurm 会跟踪每个节点的可用内存
  • 多个作业可以共享节点(如果内存足够)
  • 避免节点内存超额分配

修改 2.2:全局内存限制

位置: 第 146 行附近

原配置:

conf 复制代码
MaxMemPerNode=UNLIMITED

删除这一行,添加:

conf 复制代码
DefMemPerCPU=4096
MaxMemPerCPU=16384

原理说明:

DefMemPerCPU=4096

  • 当用户不指定 --mem 时的默认值
  • 4096MB = 4GB 每核心
  • 示例:用户执行 salloc -n 16,自动分配 64GB

MaxMemPerCPU=16384

  • 防止用户通过 --mem-per-cpu 绕过限制
  • 16384MB = 16GB 每核心
  • 示例:用户执行 salloc -n 1 --mem-per-cpu=50G 会被拒绝

为什么不用 MaxMemPerNode?

  • 全局 MaxMemPerNode 会限制所有节点
  • 您的集群节点内存不一致(64GB-512GB)
  • 应该在分区级别设置不同的限制

修改 2.3:分区级别内存限制

位置: 第 224 行开始(PARTITIONS 部分)

原配置:

conf 复制代码
PartitionName=128c2gQ Nodes=cn[01-03] Default=YES MaxTime=INFINITE State=UP
PartitionName=224c2gQ Nodes=cn04 Default=NO MaxTime=INFINITE State=UP
...

修改为:

conf 复制代码
################################################
#                  PARTITIONS                  #
################################################

# cn01-03: 257GB 节点,限制 80% = 205GB ≈ 210000MB
PartitionName=128c2gQ Nodes=cn[01-03] Default=YES MaxTime=INFINITE State=UP MaxMemPerNode=210000

# cn04: 515GB 节点,限制 80% = 412GB ≈ 420000MB
PartitionName=224c2gQ Nodes=cn04 Default=NO MaxTime=INFINITE State=UP MaxMemPerNode=420000

# cn05: 515GB 节点,限制 80% = 412GB ≈ 420000MB
PartitionName=112c3gQ Nodes=cn05 Default=NO MaxTime=INFINITE State=UP MaxMemPerNode=420000

# cn06, cn08: 63GB 节点,限制 80% = 50GB ≈ 51200MB
PartitionName=28cQ Nodes=cn[06,08] Default=NO MaxTime=INFINITE State=UP MaxMemPerNode=51200

# cn07: 191GB 节点,限制 80% = 152GB ≈ 155000MB
PartitionName=48c1vgQ Nodes=cn07 Default=NO MaxTime=INFINITE State=UP MaxMemPerNode=155000

# cn09: 257GB 节点,限制 80% = 205GB ≈ 210000MB
PartitionName=24cQ Nodes=cn09 Default=NO MaxTime=INFINITE State=UP MaxMemPerNode=210000

# cn10: 515GB 节点,限制 80% = 412GB ≈ 420000MB
PartitionName=128c4gQ Nodes=cn10 Default=NO MaxTime=INFINITE State=UP MaxMemPerNode=420000

计算公式详解:

复制代码
MaxMemPerNode = RealMemory × 0.8

示例(cn04,515GB 节点):
515072 MB × 0.8 = 412057.6 MB ≈ 420000 MB (取整)

为什么是 80%?

  • 为其他小作业预留 20% 空间
  • 例如:512GB 节点,单作业用 410GB,还剩 100GB 可运行其他任务
  • 提高节点利用率,避免资源闲置

Step 3: 修改 cgroup.conf(管理节点 + 所有计算节点)

为什么所有节点都需要修改?

原理:

  • slurm.conf 只在管理节点 (ln00)被 slurmctld 读取,用于调度决策
  • cgroup.conf每个计算节点slurmd 读取,用于资源隔离
  • 如果计算节点没有正确的 cgroup.conf,无法物理限制作业内存

架构示意:

复制代码
管理节点 (ln00)
  ├─ slurmctld (读取 slurm.conf) → 调度决策
  └─ slurmdbd → 数据库记录

计算节点 (cn01-10)
  └─ slurmd (读取 cgroup.conf) → 执行 cgroup 限制

修改内容

编辑 /etc/slurm/cgroup.conf

原配置:

conf 复制代码
CgroupAutomount=yes
ConstrainDevices=yes
ConstrainCores=yes
ConstrainRAMSpace=no

修改为:

conf 复制代码
CgroupAutomount=yes
ConstrainDevices=yes
ConstrainCores=yes
ConstrainRAMSpace=yes
AllowedRAMSpace=100
ConstrainSwapSpace=yes

参数详解:

参数 作用
CgroupAutomount yes 自动挂载 Cgroup 文件系统
ConstrainDevices yes 限制作业可访问的设备
ConstrainCores yes 限制作业可使用的 CPU 核心
ConstrainRAMSpace yes 关键! 限制作业内存使用
AllowedRAMSpace 100 允许使用申请内存的 100%
ConstrainSwapSpace yes 禁止作业使用 Swap

ConstrainRAMSpace=yes 的效果:

bash 复制代码
# 用户申请 100GB
sbatch --mem=100G job.sh

# Slurm 创建 Cgroup:
# /sys/fs/cgroup/memory/slurm/uid_xxx/job_yyy/memory.limit_in_bytes = 107374182400 (100GB)

# 作业运行时:
# - 使用 80GB → 正常运行
# - 使用 100GB → 正常运行(达到上限)
# - 尝试使用 101GB → 内核 OOM Killer 杀死进程

分发到计算节点

方法1:使用 scp(逐个复制)

bash 复制代码
for node in cn01 cn02 cn03 cn04 cn05 cn06 cn07 cn08 cn09 cn10; do
    echo "Copying to $node..."
    scp /etc/slurm/cgroup.conf root@${node}:/etc/slurm/cgroup.conf
done

方法2:使用 pdsh(并行复制)

bash 复制代码
# 如果安装了 pdsh
pdsh -w cn[01-10] "cat > /etc/slurm/cgroup.conf" < /etc/slurm/cgroup.conf

方法3:使用 Ansible(推荐用于大规模集群)

yaml 复制代码
# ansible-playbook copy-cgroup.yml
- hosts: compute_nodes
  tasks:
    - name: Copy cgroup.conf
      copy:
        src: /etc/slurm/cgroup.conf
        dest: /etc/slurm/cgroup.conf
        owner: root
        group: root
        mode: '0644'

Step 4: 重新加载配置

4.1 管理节点重新加载
bash 复制代码
# 在 ln00 执行
#不能scontrol reconfigure,不够
systemctl restart slurmctld

这个命令做了什么?

  • 重启, slurmctld 重新读取 slurm.conf
  • 新配置对新提交的作业生效

验证是否成功:

bash 复制代码
scontrol show config | grep -i select

预期输出:

复制代码
SelectType              = select/cons_tres
SelectTypeParameters    = CR_CORE_MEMORY

4.2 计算节点重启 slurmd(推荐)

虽然 scontrol reconfigure 会通知计算节点,但为确保 cgroup.conf 生效,建议重启 slurmd

方法1:逐个重启

bash 复制代码
for node in cn{01..10}; do
    echo "Restarting slurmd on $node..."
    ssh root@${node} "systemctl restart slurmd"
done

方法2:使用 scontrol(优雅重启)

bash 复制代码
# 先 drain 节点(排空作业)
scontrol update nodename=cn[01-10] state=drain reason="Config update"

# 等待作业完成...

# 重启 slurmd
for node in cn{01..10}; do
    ssh root@${node} "systemctl restart slurmd"
done

# 恢复节点
scontrol update nodename=cn[01-10] state=resume

方法3:滚动重启(推荐生产环境)

bash 复制代码
# 逐个节点重启,不影响整体服务
for node in cn{01..10}; do
    echo "Processing $node..."
    scontrol update nodename=$node state=drain reason="Config update"
    sleep 60  # 等待作业自然结束
    ssh root@${node} "systemctl restart slurmd"
    scontrol update nodename=$node state=resume
    sleep 10
done

Step 5: 验证配置

5.1 验证调度器配置
bash 复制代码
scontrol show config | grep -E "SelectType|DefMemPer|MaxMemPer"

预期输出:

复制代码
SelectType              = select/cons_tres
SelectTypeParameters    = CR_CORE_MEMORY
DefMemPerCPU            = 4096
MaxMemPerCPU            = 16384

5.2 验证节点配置
bash 复制代码
scontrol show node cn02

预期输出(关注这些字段):

复制代码
NodeName=cn02 Arch=x86_64 CoresPerSocket=32
   CPUAlloc=0 CPUTot=128 CPULoad=0.01
   AvailableFeatures=(null)
   ActiveFeatures=(null)
   Gres=gpu:2
   NodeAddr=cn02 NodeHostName=cn02 Version=21.08
   OS=Linux 5.4.0-150-generic #167-Ubuntu SMP
   RealMemory=515072 AllocMem=0 FreeMem=500000 Sockets=2
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   这里显示节点内存配置

5.3 验证分区配置
bash 复制代码
scontrol show partition 224c2gQ

预期输出:

复制代码
PartitionName=224c2gQ
   AllowGroups=ALL AllowAccounts=ALL AllowQos=ALL
   AllocNodes=ALL Default=NO QoS=N/A
   DefaultTime=NONE DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO
   MaxNodes=UNLIMITED MaxTime=INFINITE MinNodes=0 LLN=no MaxCPUsPerNode=UNLIMITED
   Nodes=cn04
   PriorityJobFactor=1 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO
   OverTimeLimit=NONE PreemptMode=OFF
   State=UP TotalCPUs=224 TotalNodes=1 SelectTypeParameters=NONE
   JobDefaults=(null)
   DefMemPerNode=UNLIMITED MaxMemPerNode=420000
                           ^^^^^^^^^^^^^^^^^^^
                           这里显示内存限制

5.4 验证 Cgroup 挂载(在计算节点)
bash 复制代码
ssh cn02 "mount | grep cgroup"

预期输出:

复制代码
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)

测试与验证

测试1:默认内存分配(按 CPU 核心)

测试命令:

bash 复制代码
salloc -n 8 -p 128c2gQ

预期行为:

  • 分配 8 个 CPU
  • 自动分配内存:8 × 4GB = 32GB

验证:

bash 复制代码
# 在另一个终端查看作业信息
squeue
scontrol show job <JOBID> | grep -i mem

预期输出:

复制代码
MinMemoryCPU=4096M MinMemoryNode=0 ...

测试2:超过 80% 限制(应该失败)

测试命令:

bash 复制代码
sbatch --mem=450G -p 224c2gQ test.sh

预期行为:

  • 224c2gQ 分区(cn04 节点)最大 420GB
  • 申请 450GB 超过限制
  • 作业提交失败

预期输出:

复制代码
sbatch: error: Batch job submission failed: Requested node configuration is not available

测试3:80% 以内(应该成功)

测试命令:

bash 复制代码
sbatch --mem=400G -p 224c2gQ test.sh

预期行为:

  • 400GB < 420GB(80% 限制)
  • 作业提交成功

预期输出:

复制代码
Submitted batch job 12345

测试4:Cgroup 内存强制限制

创建测试脚本:

bash 复制代码
cat > memory_test.sh << 'EOF'
#!/bin/bash
#SBATCH --mem=1G
#SBATCH -p 128c2gQ
#SBATCH -o mem_test_%j.out

echo "Starting memory test..."
# 尝试分配 2GB 内存(超过申请的 1GB)
python3 -c "
import time
data = []
try:
    while True:
        # 每次分配 100MB
        data.append(' ' * (100 * 1024 * 1024))
        print(f'Allocated: {len(data) * 100} MB')
        time.sleep(1)
except MemoryError:
    print('Memory allocation failed')
"
EOF

提交测试:

bash 复制代码
sbatch memory_test.sh

预期行为:

  • 作业申请 1GB 内存
  • 尝试使用超过 1GB
  • 被 Cgroup OOM Killer 杀死

查看输出:

bash 复制代码
cat mem_test_<JOBID>.out

预期输出:

复制代码
Starting memory test...
Allocated: 100 MB
Allocated: 200 MB
...
Allocated: 1000 MB
slurmstepd: error: Detected 1 oom-kill event(s) in step XXXX.batch

常见问题排查

问题1:配置修改后作业无法提交

症状:

bash 复制代码
sbatch job.sh
# 输出:Batch job submission failed: Invalid job credential

可能原因:

  • slurm.conf 语法错误
  • 配置参数冲突

排查步骤:

bash 复制代码
# 检查配置文件语法
slurmctld -t

# 查看控制器日志
tail -50 /var/log/slurmctld.log

# 常见错误示例
# error: select_g_node_init: cons_tres plugin requires memory to be configured
# → 需要设置 SelectTypeParameters=CR_Core_Memory

问题2:内存限制不生效,作业超用未被杀死

症状:

  • 作业申请 100GB
  • 实际使用 150GB
  • 没有被 OOM Killer 终止

可能原因:

  • ConstrainRAMSpace=no(未启用)
  • cgroup.conf 未分发到计算节点
  • Cgroup 未正确挂载

排查步骤:

bash 复制代码
# 1. 检查计算节点的 cgroup.conf
ssh cn02 "grep ConstrainRAMSpace /etc/slurm/cgroup.conf"
# 应该输出:ConstrainRAMSpace=yes

# 2. 检查 slurmd 日志
ssh cn02 "tail -50 /var/log/slurmd.log | grep -i cgroup"

# 3. 检查 Cgroup 是否为作业创建
ssh cn02 "ls -la /sys/fs/cgroup/memory/slurm/"
# 应该看到作业的 cgroup 目录

# 4. 查看作业的内存限制
ssh cn02 "cat /sys/fs/cgroup/memory/slurm/uid_*/job_*/memory.limit_in_bytes"

问题3:salloc 仍然占用整个节点

症状:

bash 复制代码
salloc -n 4
# 占用了整个节点的所有 CPU 和内存

可能原因:

  • SelectTypeParameters 未包含 Memory
  • DefMemPerCPU 未生效

解决方案:

bash 复制代码
# 临时解决:用户显式指定
salloc -n 4 --mem-per-cpu=4G

# 永久解决:环境变量
echo 'export SLURM_MEM_PER_CPU=4096' >> /etc/profile.d/slurm.sh
source /etc/profile.d/slurm.sh

问题4:节点状态变为 DOWN 或 DRAIN

症状:

bash 复制代码
sinfo
# 部分节点显示 down* 或 drain*

排查步骤:

bash 复制代码
# 查看节点状态原因
scontrol show node cn02

# 常见原因输出
# Reason=Not responding [slurm@2024-01-31T10:00:00]
# → slurmd 未运行

# Reason=Low memory [slurm@2024-01-31T10:00:00]
# → RealMemory 配置错误

# 恢复节点
scontrol update nodename=cn02 state=resume reason="Fixed"

问题5:修改后性能下降

症状:

  • 作业调度变慢
  • 队列中作业长时间 PENDING

可能原因:

  • 内存限制过严,可用资源减少
  • MaxMemPerNode 设置过小

解决方案:

bash 复制代码
# 查看资源可用性
sinfo -o "%P %C %m %a"

# 临时放宽限制(测试用)
scontrol update partition=128c2gQ MaxMemPerNode=250000

# 观察调度情况
squeue -o "%.18i %.9P %.8j %.8u %.2t %.10M %.6D %R"

配置文件对照表

修改前后对比

配置项 修改前 修改后 影响
SelectTypeParameters CR_Core CR_Core_Memory 内存纳入调度管理
MaxMemPerNode UNLIMITED 删除(改用分区级别) 允许不同节点不同限制
新增 DefMemPerCPU 4096 默认 4GB/核
新增 MaxMemPerCPU 16384 最大 16GB/核
分区 MaxMemPerNode 210000-420000 单作业最多 80% 节点内存
ConstrainRAMSpace no yes Cgroup 强制执行内存限制
新增 AllowedRAMSpace 100 严格限制 100%
新增 ConstrainSwapSpace yes 禁用 Swap

最佳实践建议

1. 用户教育

创建用户指南,说明新规则:

bash 复制代码
cat > /etc/motd << 'EOF'
=====================================
Slurm 集群资源使用新规则
=====================================

【内存申请】
- 默认:4GB/CPU(不指定 --mem 时)
- 最大:节点物理内存的 80%
- 示例:
  ✓ salloc -n 32           → 自动分配 128GB
  ✓ sbatch --mem=400G ...  → 512GB 节点可以
  ✗ sbatch --mem=500G ...  → 超过 80% 限制

【内存超用】
- 超出申请量会被系统自动终止
- 请合理估算作业内存需求

【帮助】
- 联系管理员:admin@example.com
=====================================
EOF

2. 监控与告警

设置监控脚本,定期检查节点状态:

bash 复制代码
#!/bin/bash
# /usr/local/bin/check_slurm_nodes.sh

NODES=$(sinfo -h -o "%n" -t down,drain)

if [ -n "$NODES" ]; then
    echo "Warning: Nodes in abnormal state:"
    echo "$NODES"
    # 发送告警邮件
    echo "$NODES" | mail -s "Slurm Node Alert" admin@example.com
fi

添加到 crontab:

bash 复制代码
crontab -e
# 每10分钟检查一次
*/10 * * * * /usr/local/bin/check_slurm_nodes.sh

3. 逐步推广

建议分阶段实施:

第一阶段(测试):

  • 仅在一个测试分区启用新配置
  • 观察 1-2 周,收集用户反馈

第二阶段(试点):

  • 扩展到部分生产分区
  • 调整参数(如 DefMemPerCPU)

第三阶段(全面):

  • 应用到所有分区
  • 完善监控和文档

4. 定期审查

每季度审查配置:

bash 复制代码
# 生成内存使用报告
sacct -S 2024-01-01 -E 2024-03-31 \
      -o jobid,user,partition,reqmem,maxrss,state \
      -X --format=JobID,User,Partition,ReqMem,MaxRSS,State > mem_report.txt

# 分析最常超内存的用户
grep OOM mem_report.txt | awk '{print $2}' | sort | uniq -c | sort -rn

总结

通过本指南的配置,您的 Slurm 集群将实现:

单作业内存限制 :最多占用节点 80% 内存,为其他作业预留空间

自动内存分配 :按 CPU 核心数自动分配(4GB/核)

强制执行 :Cgroup 物理限制,超用即终止

灵活管理 :不同节点不同限制,适应异构集群

用户友好:合理的默认值,减少用户学习成本

关键配置总结

配置文件 关键参数
slurm.conf SelectTypeParameters CR_Core_Memory
slurm.conf DefMemPerCPU 4096
slurm.conf MaxMemPerCPU 16384
slurm.conf PartitionName ... MaxMemPerNode 210000-420000
cgroup.conf ConstrainRAMSpace yes
cgroup.conf AllowedRAMSpace 100
cgroup.conf ConstrainSwapSpace yes

下一步

  1. 在测试环境验证配置
  2. 备份现有配置
  3. 按本指南逐步实施
  4. 监控集群运行状态
  5. 收集用户反馈并优化

如有问题,欢迎查阅官方文档:

相关推荐
历程里程碑2 小时前
Linux 17 程序地址空间
linux·运维·服务器·开发语言·数据结构·笔记·排序算法
CC.GG2 小时前
【Linux】进程控制(二)----进程程序替换、编写自主Shell命令行解释器(简易版)
linux·服务器·数据库
数研小生2 小时前
Full Analysis of Taobao Item Detail API taobao.item.get
java·服务器·前端
H Journey2 小时前
Linux 下添加用户相关
linux·运维·服务器·添加用户
零基础的修炼3 小时前
Linux网络---网络层
运维·服务器·网络
Trouvaille ~3 小时前
【Linux】线程同步与互斥(三):生产者消费者模型实战
linux·运维·c++·信号量·阻塞队列·生产者消费者模型·环形队列
遇见火星3 小时前
Linux Screen 命令入门指南
linux·运维·服务器
Doro再努力3 小时前
【Linux操作系统06】深入理解权限掩码与粘滞位
linux·运维·服务器
mzhan0174 小时前
[Linux] vdso 32bit vs 64bit
linux·运维·服务器