Slurm 集群内存管理与限制配置
目录
问题背景
典型场景
在多用户共享的 Slurm 集群中,经常出现以下问题:
-
问题1:资源独占
用户提交单个作业申请整个节点的全部内存(如 512GB),导致该节点无法被其他作业使用,即使该作业实际只使用了部分内存(如 200GB)。
-
问题2:内存分配不生效
管理员配置了"按 CPU 核心数自动分配内存",但用户使用
salloc或sbatch时,系统并未按预期分配,可能分配了整个节点的内存或使用了错误的默认值。
期望目标
- 限制单个作业最大内存:例如,512GB 节点最多允许单作业申请 80%(约 410GB),为其他作业预留空间
- 自动按 CPU 核心分配内存:用户申请 N 个 CPU 时,自动分配 N×X GB 内存(如 4GB/核)
- 强制执行内存限制:作业超出申请内存时,系统自动终止该作业,保护节点稳定性
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
- 超内存立即被杀死,而非性能下降后慢慢失败
配置参数深度解析
为什么 salloc 和 sbatch 行为不同?
sbatch 的默认行为
bash
sbatch job.sh
- 会使用
DefMemPerCPU的默认值 - 按申请的 CPU 数自动分配内存
salloc 的默认行为
bash
salloc -n 4
- 在某些配置下,可能请求整个节点
- 或者忽略
DefMemPerCPU,导致分配不符合预期
原因:
salloc 是交互式分配,某些 Slurm 版本对其默认行为处理不一致。
解决方案:
- 修改
SelectTypeParameters=CR_Core_Memory(核心配置) - 设置
DefMemPerCPU强制默认值 - 用户养成显式指定
--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未包含MemoryDefMemPerCPU未生效
解决方案:
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 |
下一步
- 在测试环境验证配置
- 备份现有配置
- 按本指南逐步实施
- 监控集群运行状态
- 收集用户反馈并优化
如有问题,欢迎查阅官方文档:
- Slurm Configuration: https://slurm.schedmd.com/slurm.conf.html
- Cgroup Guide: https://slurm.schedmd.com/cgroups.html