
1. 項目概述Slurm集群作業管理的核心武器如果你正在或即將使用高性能計算集群那么Slurm這個名字你一定不陌生。它不是什么美味佳肴而是當今學術界和工業界最主流的開源集群管理和作業調度系統。想象一下一個擁有成百上千個計算節點的龐大機器如何公平、高效地把計算任務分配給每個“工人”并管理好他們的工作狀態和產出這就是Slurm的職責。而作為用戶我們與這個龐大系統交互的唯一方式就是通過一系列命令行指令。今天我們就來徹底拆解這些命令從作業的“生”提交到“死”結束覆蓋你日常使用中90%以上的場景。無論你是剛接觸集群的新手還是想系統梳理知識的老手這篇基于實戰經驗的命令指南都能讓你對Slurm作業的管理游刃有余。很多朋友剛上手時面對srun、sbatch、squeue這些命令可能會感到困惑參數繁多輸出信息復雜。其實它們的核心邏輯非常清晰提交作業、查詢狀態、控制作業生命周期。掌握了這些你就掌握了在集群上開展計算工作的主動權。本文將不僅列出命令更會深入解釋每個常用參數背后的邏輯、不同命令的適用場景以及我在多年使用中踩過的坑和總結的技巧。比如如何優雅地指定GPU資源作業卡住了怎么辦如何修改一個已經提交但尚未運行的作業這些實戰問題我們都會一一找到答案。2. Slurm作業生命周期與命令全景圖在深入每個命令之前我們需要建立一個宏觀視角理解一個作業在Slurm系統中經歷的完整生命周期以及每個階段對應的核心管理命令。這就像理解一個產品的流水線知道了各個環節操作起來才能心中有數。2.1 作業生命周期的五個關鍵階段一個典型的Slurm作業通常會經歷以下五個階段提交用戶將計算任務腳本提交給Slurm調度器。此時作業進入隊列等待被調度。排隊作業在隊列中等待滿足其資源需求如CPU、內存、GPU、節點數的計算節點空閑出來。運行調度器為作業分配了資源作業開始在計算節點上執行。完成/終止作業正常執行完畢或因錯誤、被用戶手動終止而結束。后處理用戶查看作業的輸出、錯誤日志以及效率統計信息。2.2 對應各階段的核心命令家族圍繞這個生命周期Slurm提供了一套完整的命令集我們可以將其分為幾個家族提交家族負責創建和遞交作業。sbatch最常用的批處理作業提交命令。你編寫一個Shell腳本在其中通過#SBATCH指令指定資源需求然后用sbatch提交。作業會在后臺運行與你當前終端會話解耦。srun用于交互式地運行作業。它會分配資源并立即在分配的資源上執行一個命令。通常用于測試、調試或者作為sbatch腳本內部用于啟動并行任務的命令。salloc分配一個資源分配如幾個節點并獲取一個交互式的Shell。在這個Shell中你可以直接運行srun命令而無需再指定資源參數因為它們已經被salloc分配好了。適合需要交互式探索的場景。查詢家族負責監控作業和集群狀態。squeue查看作業隊列狀態的核心命令。可以查看所有作業或自己作業的排隊、運行等情況。sinfo查看集群節點狀態。可以知道哪些節點空閑、哪些節點正在工作、哪些節點下線對于理解為什么作業在排隊非常有幫助。scontrol一個功能強大的管理命令可以查看作業、節點、分區等非常詳細的信息show子命令也可以用于修改作業參數update子命令。控制家族負責干預作業的運行。scancel終止作業。可以終止單個、多個或符合特定條件的所有作業。scontrol除了查詢還能用于掛起、恢復作業。歷史與診斷家族負責查看已完成作業的信息。sacct查看已完成作業的會計信息。這是squeue的互補命令squeue看活著的作業sacct看死去的作業。可以查看作業的運行時間、消耗的CPU時間、內存使用量、退出狀態等對于性能分析和計費至關重要。seff查看指定作業ID的資源使用效率報告如CPU和內存的使用率非常直觀。理解這個全景圖后我們再深入每個命令的細節就會感覺脈絡清晰不再是一盤散沙。接下來我們從最核心的作業提交開始。3. 作業提交從腳本編寫到資源請求提交作業是萬里長征的第一步也是最容易出錯的一步。資源請求不合理可能導致作業永遠排不到隊或者一運行就因內存不足被“殺”。sbatch是這里的主角。3.1 編寫一個規范的sbatch腳本一個典型的sbatch腳本包含兩部分以#SBATCH開頭的Slurm指令和你要執行的常規Shell命令。#!/bin/bash #SBATCH --job-namemy_test_job # 作業名稱方便在隊列中識別 #SBATCH --outputslurm-%j.out # 標準輸出重定向到文件%j會被替換為作業ID #SBATCH --errorslurm-%j.err # 標準錯誤重定向到文件 #SBATCH --partitioncompute # 指定分區隊列名 #SBATCH --nodes2 # 請求的節點數 #SBATCH --ntasks-per-node4 # 每個節點上啟動的任務數通常對應MPI進程數 #SBATCH --cpus-per-task2 # 每個任務分配的CPU核心數 #SBATCH --mem-per-cpu4G # 每個CPU核心分配的內存 #SBATCH --time01:00:00 # 作業運行的最大時間時:分:秒 #SBATCH --gresgpu:2 # 請求通用資源這里是每個節點2塊GPU # 加載必要的環境模塊根據集群配置 module load cuda/11.7 module load gcc/9.3.0 # 打印一些環境信息便于調試 echo Starting job on host: $(hostname) echo Job ID: $SLURM_JOB_ID echo Allocated nodes: $SLURM_JOB_NODELIST # 這里是你的實際計算命令 # 例如運行一個MPI程序 srun ./my_mpi_program input.data # 或者運行一個非MPI的并行任務 # python my_script.py注意#SBATCH指令必須放在腳本開頭在所有可執行命令之前。Slurm在解析腳本時會讀取這些指令然后才將腳本交給Shell執行。3.2 關鍵資源參數詳解與選型邏輯為什么這么指定參數背后的考量是什么--partition分區是集群管理員根據節點硬件或用途劃分的邏輯組。比如可能有debug短時間測試、compute通用計算、gpuGPU節點、bigmem大內存節點。選型邏輯根據作業需求選擇。短測試用debug需要GPU選gpu需要超大內存選bigmem。選錯分區可能導致作業無法調度。--nodes、--ntasks-per-node、--cpus-per-task這三個參數共同定義了并行計算資源。MPI作業通常--ntasks-per-node指定每個節點的進程數總進程數 --nodes*--ntasks-per-node。--cpus-per-task為每個MPI進程綁定CPU核心提升緩存親和性。OpenMP/多線程作業可能只需要1個任務--ntasks1但需要多個CPU核心--cpus-per-task16。混合MPIOpenMP--nodes和--ntasks-per-node定義MPI進程網格--cpus-per-task定義每個MPI進程內部的OpenMP線程數。選型邏輯明確你的程序是哪種并行模式。最保險的方法是閱讀程序文檔或咨詢開發者。--mem與--mem-per-cpu指定內存。--mem指定每個節點總內存--mem-per-cpu指定每個CPU核心的內存。二選一不要同時指定。選型邏輯如果你的程序內存需求與核心數線性相關用--mem-per-cpu更靈活。如果程序有固定的基礎內存開銷用--mem更直觀。務必預留buffer不要卡著程序理論最小值申請否則可能因內存超限被Slurm強制終止。--time極其重要。這是作業運行時間上限。超時后作業會被強制終止。選型邏輯根據歷史運行經驗估算并加上一定的安全余量如20%。在debug分區時間限制通常很短如30分鐘用于快速測試。--gres請求通用資源最常見的是GPU。--gresgpu:2表示請求2塊GPU類型默認。更精確的請求可以是--gresgpu:v100:2請求2塊V100 GPU。選型邏輯確認你的代碼支持GPU加速并加載了對應的CUDA環境。3.3 提交作業與srun交互模式編寫好腳本假設名為run.slurm后使用以下命令提交sbatch run.slurm提交成功后會返回一個作業ID例如Submitted batch job 1234567。這個ID是后續查詢、控制作業的唯一憑證。交互式作業srun當你需要快速測試一個命令或者進行調試時可以使用srun。# 請求一個節點的一個核心運行10分鐘運行一個交互式bash srun --pty --nodes1 --ntasks1 --cpus-per-task1 --time00:10:00 /bin/bash進入交互式Shell后你就可以像在登錄節點一樣操作但實際是在計算節點上。退出Shell作業即結束。資源分配salloc它介于sbatch和srun之間。# 分配2個節點每個節點4個任務分配1小時 salloc --nodes2 --ntasks-per-node4 --time01:00:00命令執行后你的終端會“附著”到這個新分配的資源上命令行提示符通常會變化。在此終端中后續的srun命令會直接使用已分配的資源。# 此時運行srun無需再指定節點、任務數等參數 srun ./my_mpi_program使用exit命令退出資源釋放。4. 作業查詢與監控掌握集群動態作業提交后你不能干等著。你需要知道它是在排隊、在運行還是失敗了。squeue和sinfo是你的“監控大屏”。4.1 使用squeue洞察作業狀態squeue是最常用的查詢命令。不加任何參數它會列出所有用戶的所有作業信息量巨大。squeue輸出示例JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON) 123456 compute my_test_jo alice PD 0:00 2 (Resources) 123457 gpu train bob R 2:34 1 gpu-node-03 123458 debug quick_test carl R 0:05 1 compute-01關鍵列解析ST狀態這是最重要的列。PD排隊中。NODELIST(REASON)列會顯示排隊原因如(Resources)等待資源、(Priority)優先級低、(Dependency)等待依賴作業。R運行中。CG正在完成作業已結束Slurm在進行收尾工作。F失敗。CA已取消。TIME作業已運行時間或排隊時間對于PD狀態。NODELIST(REASON)對于運行中的作業顯示使用的節點列表對于排隊作業顯示排隊原因。常用過濾選項squeue -u $USER只看自己的作業。squeue -j 123456查看特定作業ID的詳細信息。squeue --start非常有用。顯示排隊作業的預計開始時間如果調度器能估算的話。squeue -o “%.18i %.9P %.30j %.8u %.2t %.10M %.6D %.20R”自定義輸出格式。例如這里顯示了更長的作業名和節點原因信息。4.2 使用sinfo診斷集群資源如果你的作業一直PD且原因是(Resources)就該用sinfo看看集群到底怎么了。sinfo輸出示例PARTITION AVAIL TIMELIMIT NODES STATE NODELIST compute* up infinite 2 idle compute-[01-02] compute* up infinite 1 alloc compute-03 gpu up 2-00:00:00 4 idle gpu-[01-04] gpu up 2-00:00:00 2 alloc gpu-[05-06] debug up 00:30:00 2 idle debug-[01-02]關鍵列解析STATE節點狀態idle節點空閑可用。alloc節點已被分配正在運行作業。mix節點部分資源被分配部分空閑。drain節點正在被排干管理員可能在進行維護不接受新作業。down節點宕機不可用。NODELIST處于該狀態的節點列表。常用選項sinfo -N以節點為單位顯示信息更清晰。sinfo -p compute只看compute分區的信息。sinfo -R顯示節點不可用的原因如果狀態是drain或down。通過結合squeue和sinfo你就能清晰地知道我的作業在等什么是資源不夠還是節點壞了從而決定是繼續等待還是調整作業資源請求。4.3 使用scontrol挖掘詳細信息scontrol show job jobid可以讓你看到作業的一切詳細信息遠比squeue豐富。這對于調試復雜問題至關重要。scontrol show job 123456輸出信息包括提交時間、開始時間、運行限制、資源請求詳情、使用的節點列表、工作目錄、標準輸出/錯誤路徑、依賴關系等等。當作業行為異常時這是第一手的診斷資料。5. 作業控制與修改動態管理你的計算任務計劃趕不上變化。你可能需要取消一個錯誤的作業或者修改一個還在排隊中的作業的資源需求。scancel和scontrol update是應對這些情況的工具。5.1 安全終止作業scancel的多種用法scancel用于向作業發送終止信號。取消單個作業scancel 123456取消自己所有作業scancel -u $USER慎用取消某個分區所有作業scancel -p compute取消所有排隊中的作業scancel -t PD強制終止如果作業不響應普通的終止信號可以加--signalKILL或-9選項scancel --signalKILL 123456注意對于運行中的作業scancel會先發送一個軟終止信號SIGTERM允許程序進行清理工作。如果一段時間后作業仍未結束Slurm會發送強制終止信號SIGKILL。直接使用-9會跳過軟終止階段可能導致程序產生垃圾文件或數據損壞。5.2 動態修改排隊中的作業scontrol update這是一個非常強大但容易被忽略的功能。如果你的作業還在排隊PD狀態你可以修改它的部分參數而無需取消后重新提交。可以修改的常見參數包括--time增加或減少運行時間限制。--partition切換到另一個分區。--qos修改服務質量如從普通QoS切換到高優先級QoS。--dependency修改作業依賴關系。--mail-user修改郵件通知地址。修改命令格式scontrol update jobid123456 time02:00:00 partitiongpu這條命令將作業123456的運行時間限制改為2小時并將其從當前分區移動到gpu分區。重要限制只能修改排隊中的作業。運行中的作業無法修改核心參數。修改分區或QoS可能會導致作業重新排隊因為調度器需要根據新條件重新評估。無法修改核心資源請求如節點數、CPU數、內存、GPU數因為這些是調度決策的基礎。要修改這些通常需要取消后重新提交。5.3 掛起與恢復作業在某些集群配置下管理員或擁有特定權限的用戶可以掛起和恢復作業。# 掛起作業 scontrol suspend 123456 # 恢復作業 scontrol resume 123456掛起后作業會釋放其占用的CPU資源但內存狀態會被保留在節點上。這通常用于臨時給更高優先級的作業讓路。普通用戶通常沒有此權限。6. 歷史分析與效率評估從已完成作業中學習作業運行結束后故事并沒有結束。分析作業的運行效率、資源使用情況對于優化代碼和資源請求至關重要。sacct和seff是這方面的利器。6.1 使用sacct查看會計信息sacct是查看歷史作業的瑞士軍刀功能極其強大。默認顯示最近一天的自己作業。sacct輸出示例JobID JobName Partition Account AllocCPUS State ExitCode ------------ ---------- ---------- ---------- ---------- ---------- -------- 123456 my_test_j compute alice 16 COMPLETED 0:0 123456.batch batch alice 16 COMPLETED 0:0 123456.0 my_mpi_prog alice 16 COMPLETED 0:0常用選項組合sacct -j 123456查看特定作業的詳細信息。sacct --starttime2024-01-01 --endtime2024-01-02查看指定時間段的作業。sacct -o JobID,JobName,Partition,AllocCPUS,State,Elapsed,MaxRSS,TotalCPU自定義輸出字段。Elapsed實際運行時間。MaxRSS最大常駐內存集即作業使用的最大物理內存。這是判斷你申請的內存是否合理的關鍵指標TotalCPU作業消耗的總CPU時間核心數*時間。sacct -X只顯示作業主體不顯示每個步驟如.batch.0。一個實用的分析命令sacct -j 123456 -o JobID,JobName,AllocCPUS,ReqMem,MaxRSS,State,Elapsed,TotalCPU --unitsG這條命令可以清晰地看到作業123456申請的內存ReqMem、實際使用的最大內存MaxRSS、運行狀態、耗時和總CPU消耗并且內存單位是G。如果MaxRSS遠小于ReqMem說明你申請了過多內存浪費了資源下次可以適當減少請求。6.2 使用seff快速獲取效率報告sacct功能強大但輸出可能不夠直觀。seff命令提供了一個簡潔明了的資源效率報告。seff 123456輸出示例Job ID: 123456 Cluster: mycluster User/Group: alice/alice State: COMPLETED (exit code 0) Nodes: 2 Cores per node: 8 CPU Utilized: 1-12:34:56 CPU Efficiency: 85.7% of 1-16:00:00 core-walltime Job Wall-clock time: 1-02:00:00 Memory Utilized: 12.5 GB Memory Efficiency: 31.25% of 40.00 GB這份報告一目了然CPU EfficiencyCPU利用率。85.7%是相當不錯的水平。如果這個值很低如50%說明你的程序可能不是CPU密集型或者存在大量I/O等待、同步等待需要優化。Memory Efficiency內存利用率。31.25%意味著你申請了40GB內存但只用了12.5GB。這是嚴重的資源浪費下次提交時應該將內存請求降低到16GB或20GB左右留出一些buffer即可。這樣你的作業會更容易被調度也為其他用戶釋放了資源。定期使用seff檢查作業效率是成為一個負責任、高效的集群用戶的好習慣。7. 高級技巧與實戰避坑指南掌握了基本命令后一些高級技巧和實戰中的“坑”能讓你用得更順手。7.1 作業依賴構建工作流你可以讓一個作業在另一個作業完成或成功完成后再開始運行。這對于多步驟的工作流非常有用。# 作業B在作業A完成后開始 sbatch --dependencyafterany:123456 jobB.slurm # 作業B在作業A成功完成后開始退出碼為0 sbatch --dependencyafterok:123456 jobB.slurm # 作業B在作業A結束后開始無論成功失敗 sbatch --dependencyafter:123456 jobB.slurm依賴關系可以組合--dependencyafterok:123456,afterok:123457兩個作業都成功后才開始。7.2 數組作業處理參數掃描如果你需要運行大量相似的任務例如用不同的參數運行同一個程序使用數組作業Job Array比提交幾百個獨立作業高效得多。#!/bin/bash #SBATCH --job-namearray_test #SBATCH --outputslurm-%A_%a.out # %A是主作業ID%a是數組索引 #SBATCH --array1-100 # 創建索引從1到100的數組 # 根據數組索引設置不同的輸入參數 INPUT_FILE”input_${SLURM_ARRAY_TASK_ID}.dat” OUTPUT_FILE”output_${SLURM_ARRAY_TASK_ID}.dat” ./my_program -i $INPUT_FILE -o $OUTPUT_FILE提交后Slurm會調度100個子任務。你可以用squeue看到它們作業ID類似123456_[1-100]。可以用scancel 123456_[50]取消單個子任務或用scancel 123456取消整個數組。7.3 環境變量與工作目錄在sbatch腳本中Slurm會設置一系列有用的環境變量SLURM_JOB_ID當前作業ID。SLURM_SUBMIT_DIR提交作業的目錄。SLURM_JOB_NODELIST分配給作業的節點列表。SLURM_ARRAY_TASK_ID數組作業的當前索引。SLURM_CPUS_PER_TASK每個任務分配的CPU數。一個常見的坑你的程序可能依賴某些環境變量如PATH,LD_LIBRARY_PATH這些在登錄節點設置好了但計算節點可能沒有。最佳實踐是在腳本中使用module load命令顯式加載所需環境或者使用絕對路徑調用程序和庫。7.4 輸出與錯誤日志管理#SBATCH --output和#SBATCH --error務必重定向。否則輸出會混在一起難以調試。對于長時間運行或輸出量大的作業可以考慮在腳本內部將輸出重定向到文件而不是完全依賴Slurm的重定向。使用tail -f slurm-123456.out可以實時跟蹤運行中的作業輸出在登錄節點執行。7.5 資源請求的黃金法則時間盡可能準確地估計并加10-20%緩沖。申請時間過長會降低調度優先級申請時間過短會被強制殺死。內存通過測試小規模任務用seff估算MaxRSS然后按比例放大到全規模并增加20-30%的安全余量。不要盲目申請超大內存。CPU/GPU匹配你的程序并行能力。一個只能串行的程序申請16個核心只會浪費15個核心。使用性能分析工具如gprof,nvprof了解你的程序。分區選擇合適的隊列。在debug隊列做短測試在gpu隊列跑GPU任務。7.6 當作業出問題時作業一直PD用squeue --start看預計時間。用scontrol show job看詳細信息。用sinfo檢查目標分區資源是否緊張或節點是否drain/down。考慮調整資源請求或換分區。作業運行失敗狀態為FAILED首先檢查錯誤日志文件slurm-jobid.err。常見原因內存超限Out Of Memory、運行超時、依賴的軟件模塊未加載、輸入文件路徑錯誤、權限問題。作業被終止狀態為CANCELLED可能是你或他人用scancel終止了也可能是系統管理員因維護需要終止的。檢查郵件通知或聯系管理員。程序運行慢登錄計算節點通過srun --pty bash使用top、htop、nvidia-smiGPU作業等命令查看資源實際使用情況。可能是I/O瓶頸、內存交換、或者程序本身并行效率低。掌握這些命令和技巧你就能從Slurm的“用戶”進階為“管理者”從容應對集群上的各種計算任務。記住清晰的資源請求、高效的代碼和定期的效率分析不僅是對自己負責也是對共享集群資源的其他用戶的尊重。