Slurm (Simple Linux Utility for Resource Management, http://slurm.schedmd.com/ )是一個開源的、具有容錯性、高度可擴展的集羣管理和作業調度系統,適用於大型和小型 Linux 集羣。Slurm 不需要對內核進行修改,它的運行方式相對獨立以避免節點相互干擾,提高運行效率。
作為集羣工作負載管理器, Slurm 具有三個關鍵功能。首先,它分配獨佔和或非獨佔節點提供給用户在一段時間內訪問資源(計算節點),以便他們可以執行業務計算。其次,它提供了一個用於啓動、執行和監視分配節點上的工作(通常是並行作業)的框架。最後它通過管理待處理作業的隊列來仲裁資源爭用。所有需運行的作業,無論是用於程序調試還是業務計算,都可以通過交互式並行 srun 、批處理式 sbatch 或分配式 salloc 等命令提交,提交後可以利用相關命令查詢作業狀態等。
為了更有效地管理和分配資源,優化作業調度,提升系統利用率,並滿足多樣化的作業需求,隊列成為任務調度中不可或缺的配置項。合理的隊列設置能夠確保高優先級的任務優先獲得所需資源,從而最大化資源利用效率。
本文介紹在Slurm系統環境下,當出現作業提交或作業狀態變化時,如何通過恰當的隊列配置策略來實現儘可能多的任務調度處理,以達到最佳性能。
一、Slurm隊列類型
Slurm任務按優先級排序執行,若分區存在不可調度任務,則後續任務暫停。高優先級任務可搶佔低優先級任務資源,被搶佔任務可以取消、重置或掛起。如果您啓用回填調度(默認),按 bf_interval 週期計算低優任務能否在不延遲高優任務前提下運行,需佔用整機資源並可能觸發整機搶佔。調度配置通過 slurm.conf 指定 SchedulerType (默認 sched/backfill 插件)及詳細參數 SchedulerParameters ,具體參數配置,請參見官方文檔(https://slurm.schedmd.com/sched_config.html)。
在調度過程中,所有任務都會被整合到一個列表中,並通過不同的優先級算法來確定執行順序。Slurm支持以下兩種隊列類型:
- 先進先出(FIFO)隊列,任務的排序依據是它們提交的時間順序。
- 多因素(MultiFactors)隊列,是一種更高級的任務排隊機制,默認處於啓用狀態,它能夠根據多個因素綜合計算作業的優先級。
1. 先進先出(FIFO)隊列
默認情況下,Slurm採用先進先出FIFO為基礎分配作業優先級。關於優先級調度的配置文件存放 slurm.conf 中,可以通過修改參數 PriorityType 來配置優先級。
# 1.找到並編輯slurm.conf文件
sudo nano /etc/slurm/slurm.conf
# 2.啓用搶佔模式,並指定基於先進先出優先級的搶佔策略
PriorityType=priority/basic
2. 多因素(MultiFactors)隊列
Slurm多因素調度通過加權計算以下因子確定任務優先級:作業執行時長、資源差異(已分配vs已消耗)、作業規模、用户參數、數據分區、TRES(資源等價值)類型及服務質量(QOS)。權重分配與具體計算邏輯,請參見多因素優先級配置説明(https://slurm.schedmd.com/priority_multifactor.html)。
Job_priority =
site_factor +
(PriorityWeightAge) * (age_factor) +
(PriorityWeightAssoc) * (assoc_factor) +
(PriorityWeightFairshare) * (fair-share_factor) +
(PriorityWeightJobSize) * (job_size_factor) +
(PriorityWeightPartition) * (priority_job_factor) +
(PriorityWeightQOS) * (QOS_factor) +
SUM(TRES_weight_cpu * TRES_factor_cpu,
TRES_weight_<type> * TRES_factor_<type>,
...)
- nice_factor
Slurm作業優先級通過以下加權因子計算:
- 基礎值:site_factor(自定義分值)。
- 作業等待時間權重:作業等待時間越長,權重越高(PriorityWeightAge × age_factor)。
- 關聯權重:用户組/賬户的資源使用公平性(PriorityWeightAssoc × assoc_factor)。
- 公平共享權重:按資源使用比例調整分值(PriorityWeightFairshare × fair-share_factor)。
- 作業大小權重:小/大作業優先(PriorityWeightJobSize × job_size_factor)。
- 分區權重:分區優先級(PriorityWeightPartition × priority_job_factor)。
- QoS權重:服務質量等級(PriorityWeightQOS × QOS_factor)。
- 資源權重:資源類型(CPU/GPU等)權重加權。
- Nice降級:- nice_factor(數值越大,優先級越低)。
您可以通過動態調整權重參數,實現公平、高效的任務調度。
典型應用示例:
- 快速完成小作業:設置 PriorityWeightJobSize=-1,大作業的優先級降低,小作業更快被調度。
- 保障關鍵用户/組:通過 PriorityWeightAssoc 和 Fair-share_factor 確保重要團隊的作業優先運行。
- 資源飢餓保護:配置 PriorityWeightFairshare=2000,低資源使用量的用户作業優先級顯著提升。
二、設置多因素作業優先級
1. 設置分區優先級
- 在配置文件中打開搶佔功能開關,搶佔類型設置為 preempt/partition_prio。
# 1.找到並編輯slurm.conf文件
sudo nano /etc/slurm.conf
# 2.啓用搶佔模式,並指定基於分區優先級的搶佔策略
PreemptType=preempt/partition_prio
# 3.當作業被搶佔時的行為,定義了當一個作業被搶佔時會發生什麼。# cancel表示取消該作業;suspend則會暫停它直到資源再次可用。。
PreemptMode=suspend # 或者 "cancel"
- 相關參數
|
參數 |
推薦值 |
作用 |
|
SelectType |
select/cons_tres |
定義資源分配策略,指定如何將任務分配到節點資源上。説明:由slurm cluster創建出的worker使用了dynamic node特性,因此只支持select/cons_tres類型。 |
|
SelectTypeParameters |
CR_Core |
傳遞給SelectType插件的具體參數,控制資源分配細節。 |
|
SchedulerType |
sched/backfill |
指定調度算法類型,決定任務如何被安排至節點。 |
|
PriorityType |
priority/multifactor |
定義任務優先級計算規則,決定任務調度順序。 |
|
PreemptMode |
SUSPEND,GANG |
啓用搶佔策略的條件,即決定在什麼情況下允許搶佔運行中的任務。説明:開啓搶佔時,在select/cons_tres類型的select插件下只允許使用SUSPEND、GANG。 |
|
PreemptType |
preempt/partition_prio |
選擇搶佔機制類型,指定具體如何執行搶佔行為。説明當前支持preempt/qos與preempt/partition_prio,本例中使用分區作為搶佔的依據。 |
- 添加一個高優先級分區
在slurm.conf中新增一條分區記錄如:
# sudo nano /etc/slurm/slurm.conf
...
NodeName=rhel-efserver NodeAddr=192.168.1.25 CPUs=8 CoresPerSocket=2 ThreadsPerCore=1 RealMemory=1024 Procs=1 State=UNKNOWN
NodeName=rhel-compute NodeAddr=192.168.1.24 CPUs=16 CoresPerSocket=2 ThreadsPerCore=1 RealMemory=10240 Procs=1 State=UNKNOWN
NodeName=rhel-dcv NodeAddr=192.168.1.26 CPUs=8 CoresPerSocket=2 ThreadsPerCore=1 RealMemory=8192 Procs=1 State=UNKNOWN
NodeName=rhel-openscow NodeAddr=192.168.1.28 CPUs=16 CoresPerSocket=2 ThreadsPerCore=1 RealMemory=4096 Procs=1 State=UNKNOWN
NodeName=rhel-login NodeAddr=192.168.1.27 CPUs=8 CoresPerSocket=2 ThreadsPerCore=1 RealMemory=2048 Procs=1 State=UNKNOWN
PartitionName=compute Nodes=rhel-compute Default=YES MaxTime=INFINITE State=UP OverSubscribe=FORCE:1
PartitionName=dcv Nodes=rhel-dcv Default=NO MaxTime=INFINITE State=UP
PartitionName=debug Nodes=rhel-dcv,rhel-efserver,rhel-compute,rhel-openscow,rhel-login Default=NO MaxTime=INFINITE State=UP
# high_prio_debug分區優先級Priority=10000,其他默認為1
PartitionName=high_prio_debug Nodes=rhel-dcv,rhel-efserver,rhel-compute,rhel-openscow,rhel-login Priority=10000 Default=NO MaxTime=INFINITE State=UP
查看分區信息:
[root@rhel-openscow ~]# scontrol show partitions
PartitionName=compute
AllowGroups=ALL AllowAccounts=ALL AllowQos=ALL
AllocNodes=ALL Default=YES QoS=N/A
DefaultTime=NONE DisableRootJobs=NO ExclusiveUser=NO ExclusiveTopo=NO GraceTime=0 Hidden=NO
MaxNodes=UNLIMITED MaxTime=UNLIMITED MinNodes=0 LLN=NO MaxCPUsPerNode=UNLIMITED MaxCPUsPerSocket=UNLIMITED
Nodes=rhel-compute
PriorityJobFactor=1 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=FORCE:1
OverTimeLimit=NONE PreemptMode=GANG,SUSPEND
State=UP TotalCPUs=16 TotalNodes=1 SelectTypeParameters=NONE
JobDefaults=(null)
DefMemPerNode=UNLIMITED MaxMemPerNode=UNLIMITED
TRES=cpu=16,mem=10G,node=1,billing=16
PartitionName=dcv
AllowGroups=ALL AllowAccounts=ALL AllowQos=ALL
AllocNodes=ALL Default=NO QoS=N/A
DefaultTime=NONE DisableRootJobs=NO ExclusiveUser=NO ExclusiveTopo=NO GraceTime=0 Hidden=NO
MaxNodes=UNLIMITED MaxTime=UNLIMITED MinNodes=0 LLN=NO MaxCPUsPerNode=UNLIMITED MaxCPUsPerSocket=UNLIMITED
Nodes=rhel-dcv
PriorityJobFactor=1 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO
OverTimeLimit=NONE PreemptMode=GANG,SUSPEND
State=UP TotalCPUs=8 TotalNodes=1 SelectTypeParameters=NONE
JobDefaults=(null)
DefMemPerNode=UNLIMITED MaxMemPerNode=UNLIMITED
TRES=cpu=8,mem=8G,node=1,billing=8
PartitionName=debug
AllowGroups=ALL AllowAccounts=ALL AllowQos=ALL
AllocNodes=ALL Default=NO QoS=N/A
DefaultTime=NONE DisableRootJobs=NO ExclusiveUser=NO ExclusiveTopo=NO GraceTime=0 Hidden=NO
MaxNodes=UNLIMITED MaxTime=UNLIMITED MinNodes=0 LLN=NO MaxCPUsPerNode=UNLIMITED MaxCPUsPerSocket=UNLIMITED
Nodes=rhel-compute,rhel-dcv,rhel-efserver,rhel-login,rhel-openscow
PriorityJobFactor=1 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO
OverTimeLimit=NONE PreemptMode=GANG,SUSPEND
State=UP TotalCPUs=56 TotalNodes=5 SelectTypeParameters=NONE
JobDefaults=(null)
DefMemPerNode=UNLIMITED MaxMemPerNode=UNLIMITED
TRES=cpu=56,mem=25G,node=5,billing=56
PartitionName=high_prio_debug
AllowGroups=ALL AllowAccounts=ALL AllowQos=ALL
AllocNodes=ALL Default=NO QoS=N/A
DefaultTime=NONE DisableRootJobs=NO ExclusiveUser=NO ExclusiveTopo=NO GraceTime=0 Hidden=NO
MaxNodes=UNLIMITED MaxTime=UNLIMITED MinNodes=0 LLN=NO MaxCPUsPerNode=UNLIMITED MaxCPUsPerSocket=UNLIMITED
Nodes=rhel-compute,rhel-dcv,rhel-efserver,rhel-login,rhel-openscow
PriorityJobFactor=10000 PriorityTier=10000 RootOnly=NO ReqResv=NO OverSubscribe=NO
OverTimeLimit=NONE PreemptMode=GANG,SUSPEND
State=UP TotalCPUs=56 TotalNodes=5 SelectTypeParameters=NONE
JobDefaults=(null)
DefMemPerNode=UNLIMITED MaxMemPerNode=UNLIMITED
TRES=cpu=56,mem=25G,node=5,billing=56
連續提交多個任務:srun sleep 1d &
[root@rhel-openscow ~]# squeue
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
61 compute sleep root PD 0:00 1 (Priority)
60 compute sleep root PD 0:00 1 (Resources)
58 compute sleep root R 0:17 1 rhel-compute
59 compute sleep root R 0:17 1 rhel-compute
56 compute sleep root R 0:18 1 rhel-compute
57 compute sleep root R 0:18 1 rhel-compute
54 compute sleep root R 0:19 1 rhel-compute
55 compute sleep root R 0:19 1 rhel-compute
52 compute sleep root R 0:20 1 rhel-compute
53 compute sleep root R 0:20 1 rhel-compute
50 compute sleep root R 0:21 1 rhel-compute
51 compute sleep root R 0:21 1 rhel-compute
48 compute sleep root R 0:22 1 rhel-compute
49 compute sleep root R 0:22 1 rhel-compute
47 compute sleep root R 0:23 1 rhel-compute
45 compute sleep root R 0:24 1 rhel-compute
46 compute sleep root R 0:24 1 rhel-compute
44 compute sleep root R 0:26 1 rhel-compute
在高優先級分區 high_prio_debug 提交任務:
# 任務44的ST(狀態)從R變為了S,任務62的狀態變為了R,説明任務44被掛起,任務62搶佔資源運行
[root@rhel-openscow ~]# srun --partition=high_prio_debug -w rhel-compute sleep 1d &
[19] 62843
[root@rhel-openscow ~]#
[root@rhel-openscow ~]# squeue
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
60 compute sleep root PD 0:00 1 (Resources)
61 compute sleep root PD 0:00 1 (Priority)
58 compute sleep root R 0:52 1 rhel-compute
59 compute sleep root R 0:52 1 rhel-compute
56 compute sleep root R 0:53 1 rhel-compute
57 compute sleep root R 0:53 1 rhel-compute
54 compute sleep root R 0:54 1 rhel-compute
55 compute sleep root R 0:54 1 rhel-compute
52 compute sleep root R 0:55 1 rhel-compute
53 compute sleep root R 0:55 1 rhel-compute
50 compute sleep root R 0:56 1 rhel-compute
51 compute sleep root R 0:56 1 rhel-compute
48 compute sleep root R 0:57 1 rhel-compute
49 compute sleep root R 0:57 1 rhel-compute
47 compute sleep root R 0:58 1 rhel-compute
45 compute sleep root R 0:59 1 rhel-compute
46 compute sleep root R 0:59 1 rhel-compute
44 compute sleep root S 0:56 1 rhel-compute
62 high_prio sleep root R 0:05 1 rhel-compute
更新任務為高優先級任務:
# 任務60立即運行,任務45的ST(狀態)從R變為了S,説明任務45被掛起,任務60搶佔資源運行
[root@rhel-openscow ~]# scontrol update jobid=60 partition=high_prio_debug nodelist=rhel-compute
[root@rhel-openscow ~]# srun: job 60 has been allocated resources
[root@rhel-openscow ~]# squeue
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
61 compute sleep root PD 0:00 1 (Resources)
58 compute sleep root R 5:21 1 rhel-compute
59 compute sleep root R 5:21 1 rhel-compute
56 compute sleep root R 5:22 1 rhel-compute
57 compute sleep root R 5:22 1 rhel-compute
54 compute sleep root R 5:23 1 rhel-compute
55 compute sleep root R 5:23 1 rhel-compute
52 compute sleep root R 5:24 1 rhel-compute
53 compute sleep root R 5:24 1 rhel-compute
50 compute sleep root R 5:25 1 rhel-compute
51 compute sleep root R 5:25 1 rhel-compute
48 compute sleep root R 5:26 1 rhel-compute
49 compute sleep root R 5:26 1 rhel-compute
47 compute sleep root R 5:27 1 rhel-compute
46 compute sleep root R 5:28 1 rhel-compute
45 compute sleep root S 5:20 1 rhel-compute
44 compute sleep root S 0:56 1 rhel-compute
60 high_prio sleep root R 0:08 1 rhel-compute
62 high_prio sleep root R 4:34 1 rhel-compute
2. 設置QOS服務質量優先級
Slurm需配置高/低優先級QOS(默認已存在優先級0的 normal),並通過 sacctmgr 創建高優QOS啓用搶佔。需在 slurm.conf 開啓搶佔功能(如 PreemptMode=priority)。
但需注意:若 PreemptType=SUSPEND,GANG ,高優任務搶佔後,低優任務會以分時模式與高優任務共存(非完全中斷)。配置QOS需要使用 sacctmgr 工具,以下是創建一個高優QOS的常用命令。
sacctmgr add qos high preempt=normal preemptmode=gang,suspend priority=10
- preempt=normal:指定 high QoS可搶佔 normal QoS的任務。
- preemptmode=gang,suspend:
- Gang模式:搶佔任務需完全獲取資源後才開始執行。
- Suspend模式:被搶佔任務暫停而非終止,釋放資源供搶佔者使用,待搶佔任務結束時恢復執行。
- priority=10:high QoS任務默認優先級基分為10(數值越高優先級越高)。 在slurm.conf中打開搶佔相關開關涉及到以下參數,同時在配置Partition時,需要在配置的最後增加OverSubscribe=FORCE:1。
|
參數 |
推薦值 |
作用 |
|
SelectType |
select/cons_tres |
定義資源分配策略,指定如何將任務分配到節點資源上。説明:由slurm cluster創建出的worker使用了dynamic node特性,因此只支持select/cons_tres類型。 |
|
SelectTypeParameters |
CR_Core |
傳遞給SelectType插件的具體參數,控制資源分配細節。 |
|
SchedulerType |
sched/backfill |
指定調度算法類型,決定任務如何被安排至節點。 |
|
PriorityType |
priority/multifactor |
定義任務優先級計算規則,決定任務調度順序。 |
|
PreemptMode |
SUSPEND,GANG |
啓用搶佔策略的條件,即決定在什麼情況下允許搶佔運行中的任務。説明:開啓搶佔時,在select/cons_tres類型的select插件下只允許使用SUSPEND、GANG。 |
|
PreemptType |
preempt/qos |
選擇搶佔機制類型,指定具體如何執行搶佔行為。説明:當前支持preempt/qos與preempt/partition_prio,本例中使用QOS作為搶佔的依據。 |
查看當前QOS:
[root@rhel-openscow ~]# sacctmgr show qos format=name
Name
----------
normal
low
創建高優先級QOS:
[root@rhel-openscow ~]# sacctmgr add qos high preempt=normal preemptmode=gang,suspend priority=10
Adding QOS(s)
high
Settings
Description = high
Preempt = normal
PreemptMode = GANG,SUSPEND
Priority = 10
Would you like to commit changes? (You have 30 seconds to decide)
(N/y): y
[root@rhel-openscow ~]#
[root@rhel-openscow ~]# sacctmgr show qos format=name
Name
----------
normal
low
high
[root@rhel-openscow ~]# sacctmgr show qos format=name,priority,preempt
Name Priority Preempt
---------- ---------- ----------
normal 0
low 0
high 10 normal
新建測試腳本:
# sudo nano test.sh
#!/bin/bash
srun sleep 10m
連續提交多個任務:
# sbatch test.sh
# ...
[root@rhel-openscow ~]# squeue
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
79 compute test.sh root PD 0:00 1 (Resources)
77 compute test.sh root R 0:07 1 rhel-compute
78 compute test.sh root R 0:07 1 rhel-compute
73 compute test.sh root R 0:10 1 rhel-compute
74 compute test.sh root R 0:10 1 rhel-compute
75 compute test.sh root R 0:10 1 rhel-compute
76 compute test.sh root R 0:10 1 rhel-compute
71 compute test.sh root R 0:13 1 rhel-compute
72 compute test.sh root R 0:13 1 rhel-compute
67 compute test.sh root R 0:14 1 rhel-compute
68 compute test.sh root R 0:14 1 rhel-compute
69 compute test.sh root R 0:14 1 rhel-compute
70 compute test.sh root R 0:14 1 rhel-compute
64 compute test.sh root R 0:17 1 rhel-compute
65 compute test.sh root R 0:17 1 rhel-compute
66 compute test.sh root R 0:17 1 rhel-compute
63 compute test.sh root R 0:20 1 rhel-compute
向高優先級QOS提交任務:
# 高優先級QOS任務開始執行,通過分時的方式與其他任務共享資源
[root@rhel-openscow ~]# sbatch -w rhel-compute --qos=high test.sh
Submitted batch job 80
[root@rhel-openscow ~]# squeue
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
79 compute test.sh root PD 0:00 1 (Resources)
77 compute test.sh root R 0:44 1 rhel-compute
78 compute test.sh root R 0:44 1 rhel-compute
73 compute test.sh root R 0:47 1 rhel-compute
74 compute test.sh root R 0:47 1 rhel-compute
75 compute test.sh root R 0:47 1 rhel-compute
76 compute test.sh root R 0:47 1 rhel-compute
71 compute test.sh root R 0:50 1 rhel-compute
72 compute test.sh root R 0:50 1 rhel-compute
67 compute test.sh root R 0:51 1 rhel-compute
68 compute test.sh root R 0:51 1 rhel-compute
69 compute test.sh root R 0:51 1 rhel-compute
70 compute test.sh root R 0:51 1 rhel-compute
64 compute test.sh root R 0:54 1 rhel-compute
65 compute test.sh root R 0:54 1 rhel-compute
66 compute test.sh root R 0:54 1 rhel-compute
63 compute test.sh root R 0:57 1 rhel-compute
80 compute test.sh root S 0:00 1 rhel-compute
3. 設置作業大小優先級
作業大小優先級是由 PriorityWeightJobSize 和 PriorityWeightAge=1000 共同決定。
作業大小因素
非緊急任務需高效利用集羣資源(不超期限)。當任務執行時間未知時,回填調度失效,此時優先調度小任務減少隊頭阻塞,同時依據排隊時間提升大任務優先級防餓死;臨近截止的大任務可搶佔小任務資源(掛起小任務直至其完成)。
為提高非緊急任務集羣利用率(不超過截止時間),您可以採取以下策略進行設置:
- 優先調度小任務減少隊頭阻塞。
- 按排隊時長提升大任務優先級防餓死。
- 臨近截止的大任務可搶佔小任務資源(小任務掛起至其完成)。任務執行時間未知時,回填調度失效,需以上機制保障資源高效利用。
通過實施上述措施,可以在保證關鍵任務按時完成的同時最大化利用集羣資源,同時也兼顧了不同類型任務之間的平衡。
在slurm.conf中需要進行如下的配置(這裏只展示特殊配置,slurm.conf中的其他配置不受影響):
PriorityFavorSmall=YES
PriorityWeightAge=1000
PriorityWeightJobSize=1000
PriorityMaxAge=1-0
作業等待時間因素
- 當設置完成作業大小優先級後,提交後等待時間為第二因素。Slurm通過任務請求資源與集羣總資源的佔比計算任務大小得分;若啓用 PriorityFavorSmall=YES ,得分公式為:得分 = (1 - 資源佔比) × PriorityWeightJobSize。例如,當集羣可用4核CPU時:
- 請求1核任務得分: (1 - 1/4) × 權重 = 0.75×權重 → 示例得分為0.375(若權重為0.5) 。
- 請求4核任務得0分(完全佔用資源)。
- AgeFactor優先級計算:
- 超過 PriorityMaxAge 的任務:直接得 PriorityWeightAge 全分。
- 其他任務按提交時間佔比得分,例如設置 PriorityWeightAge=1000 時,每分鐘增加約0.69分,累計至24小時後得滿分1000。
- 回填調度建議,若可預估任務執行時間,建議啓用默認的回填調度(或手動配置 SchedulerType=sched/backfill ),使其通過時間表調度小任務填充至大任務空閒時段。結合系統默認的大任務優先機制及臨近截止時間搶佔功能,可平衡資源利用率與公平性。