Linux伺服器PBS任務佇列作業提交指令碼的使用方法

疯狂学习GIS發表於2024-07-26

  本文介紹在Linux伺服器中,透過PBS(Portable Batch System)作業管理系統指令碼的方式,提交任務到伺服器佇列,並執行任務的方法。

  最近,需要在學校公用的超算中執行程式碼任務;而和多數超算裝置一樣,其也是需要透過作業佇列的方式,來提交、管理、排序不同使用者的任務,從而使得不同使用者都可以較為公平地使用超算裝置的資源。由於學校的這個超算是基於PBS來提交任務的,所以這裡就介紹一下撰寫PBS指令碼,從而將自己的程式碼執行需求提交給伺服器(也就是提交任務)的方法。

  其中,PBS(Portable Batch System)是一個用於管理、排程計算任務的開源軟體;其是一個常用的作業排程系統,用於在大規模計算叢集或超級計算機上管理並分配計算資源。在使用時,我們需要首先提交作業到計算叢集,PBS將會根據資源可用性、作業優先順序等因素進行作業排程和分配。其基本工作流程如下:

  • 使用者編寫PBS指令碼,描述任務的資源需求、執行命令和其他相關資訊。
  • 使用者使用PBS命令,將上述編寫好的指令碼提交到PBS系統。
  • PBS系統根據指令碼中作業的資源需求和叢集的可用資源情況,將作業放入作業佇列中等待執行。
  • 當有可用的計算資源時,PBS系統會選擇一個作業並將其分配給相應的計算節點。
  • 作業在計算節點上執行,直到完成,或達到預設的執行時間限制,或任務執行時出錯等。

  那麼接下來,就介紹一下撰寫PBS指令碼,並基於其提交自己的任務到伺服器中的方法。

  首先明確一下本文的需求。已知當前在伺服器的某個路徑下,我們有一個可執行檔案(或者是有1Python程式碼檔案);我們希望後續在超算中,對這個可執行檔案(或者Python程式碼檔案)加以執行。

  明確了需求,接下來就可以開始操作。首先,如果有需要,我們可以cd進入自己的工作目錄。我這裡就直接進入存放有可執行檔案的目錄中;具體程式碼如下。

cd Data_Reflectance_Rec

  隨後,基於如下程式碼檢視一下當前路徑中的檔案。ls用於列出目錄中的檔案和子目錄。

ls

  接下來,基於如下程式碼建立PBS指令碼,我在這裡將其命名為py_task.pbs;其中,.pbs就是PBS指令碼檔案的固定擴充名。後續我們向PBS系統提交任務時所用的指令碼,就是這個檔案。

touch py_task.pbs

  其中,touch是一個常用的命令,用於建立空白檔案或更新已存在檔案的訪問和修改時間戳。建立完畢後,可以基於如下程式碼再次看一下當前路徑下的檔案。

ls

  執行上述程式碼,如下圖所示。可以看到,py_task.pbs這個PBS指令碼檔案已經建立完畢了。

  建立指令碼檔案完畢後,我們即可開始編輯這個檔案。在這裡,我選擇基於Vim來編輯,所以執行如下的程式碼即可。

vim py_task.pbs

  其中,Vim是一個強大的文字編輯器,廣泛用於命令列環境下程式碼的編寫和文字的編輯。執行上述程式碼,如下圖所示。可以看到,py_task.pbs這個PBS指令碼檔案已經被Vim開啟了。

  接下來,按下i鍵,進入文字編輯狀態;如下圖所示。

  隨後,即可在Vim中編輯PBS指令碼檔案。在這裡,我們給出2PBS指令碼檔案的模板;其中,第1個模板如下所示。

#!/bin/bash
#PBS -N py_task
#PBS -q rtlab1_4
#PBS -l nodes=1:ppn=4
#PBS -l walltime=00:30:00
#PBS -o /data1/home/LiliAircas/Data_Reflectance_Rec/task/py_task.out
#PBS -e /data1/home/LiliAircas/Data_Reflectance_Rec/task/py_task.err
hostname
date "+%Y/%m/%d %H:%M:%S"
python /data1/home/LiliAircas/Data_Reflectance_Rec/code/Alignment.py
date "+%Y/%m/%d %H:%M:%S"
最後注意記得留一個空行

  其中,第1行是一個shebang(也稱為hashbang)行,指定了用於解釋該指令碼的直譯器。在這裡,/bin/bash表示該指令碼將由Bash直譯器執行。

  接下來,從第2行開始的這些#開頭的語句,不是註釋,而是PBS作業排程系統的作業指令。這些指令以#PBS開頭,指定了不同的選項:-N py_task表示作業的名稱為py_task-q rtlab1_4表示將作業提交到rtlab1_4佇列中;-l nodes=1:ppn=4表示指定使用1個節點(node)和4個處理器(processor)來執行作業;-l walltime=00:30:00表示作業的最長執行時間為30分鐘。隨後的2行程式碼,分別指定了作業的標準輸出錯誤輸出所在的檔案。

  緊接著,隨後的2行分別輸出當前執行指令碼的主機名和當前的日期時間;隨後,就開始呼叫Python直譯器執行Alignment.py這個Python程式碼檔案了。最後,再次輸出當前的日期時間,從而使得我們可以基於其大概瞭解到任務的執行時長。

  最後的空行,有的教程說是為了符合指令碼檔案的規範,提供可讀性和結構上的清晰性;也有教程說,有些版本的伺服器上如果不加這個空行,會導致無法識別指令碼命令。所以為了確保萬一,我就加上了1行空行。

  上述指令碼檔案編輯完畢後,如下圖所示。這裡需要注意:以下截圖中有些錯誤,例如hostname寫成了Hostname,且最後一行沒有空行。所以對於圖片,大家僅僅參考就好;主要還是按照前述文字版程式碼中的格式,來修改自己的PBS指令碼檔案。

  此外,我們再給出1PBS指令碼執行可執行檔案的模板,具體如下。

#!/bin/bash
#PBS -N py_task
#PBS -q rtlab1_4
#PBS -l nodes=1:ppn=1
#PBS -l walltime=12:00:00
#PBS -o /data1/home/LiliAircas/Data_Reflectance_Rec/code/py_task.out
#PBS -e /data1/home/LiliAircas/Data_Reflectance_Rec/code/py_task.err
hostname
date "+%Y/%m/%d %H:%M:%S"
cd /data1/home/LiliAircas/Data_Reflectance_Rec/code
./Alignment_Server
date "+%Y/%m/%d %H:%M:%S"

  其中,指令碼檔案的含義前面已經介紹過,這裡我們就不再逐一介紹了。

  在Vim中編輯完畢自己的指令碼檔案後,即可儲存並退出Vim。首先,我們需要按下Esc鍵,退出編輯模式;隨後,依次輸入:wq3個按鍵,即可儲存並退出VIm

  隨後,我們即可提交自己的PBS指令碼檔案到系統中;透過如下的程式碼即可實現這一功能。

qsub py_task.pbs

  上述程式碼會將我們前述編輯好的PBS指令碼檔案py_task.pbs提交到PBS作業排程系統中,並開始等待系統分配資源,從而執行作業。執行上述程式碼,如下圖所示。

  如果沒有問題的話,會出如上圖所示的一個編號;這個就是我們剛剛提交的任務的ID

  當然,有的時候執行上述程式碼,會出現如下圖所示的錯誤,即qsub: submit error (Unauthorized Request...)字樣的報錯。

  這種多數是因為將作業提交到了沒有許可權的佇列中導致的;這種情況,需要和伺服器的管理人員聯絡,從而獲取許可權。

  接下來,再介紹幾個PBS系統的常用命令。

  首先,我們可以透過如下程式碼,獲取當前超算的所有節點的情況。

pbsnodes

  執行上述程式碼,如下圖所示;可以看到,不同節點的資訊都列出來了。

  還可以在上述命令的後面,加上具體節點的名稱,從而只獲取指定節點的資訊;如以下程式碼。

pbsnodes cu02

  執行上述程式碼,如下圖所示;其中,和上圖一樣,每一個當前正在該節點上執行的任務的ID,都會被顯示出來,例如下圖中紫色框內就是某個任務的ID

  其次,我們可以透過如下程式碼,獲取當前佇列中所有任務的情況。

qstat

  執行上述程式碼,如下圖所示;可以看到有一個任務,這個任務是我自己提交的。在我這裡,執行上述程式碼後只能看到自己提交的任務,而看不到佇列中同時存在的、其他人提交的任務——感覺這個可能是我們學校伺服器管理人員自行設定的,使得每一個使用者僅僅只能看到自己賬戶中提交的任務。

  再次,還可以透過如下的程式碼,檢視佇列中任務的詳細資訊。

qstat -f

  執行上述程式碼,如下圖所示。

  此外,可以透過qdel命令加上任務的ID,刪除佇列中的指定任務;例如以下程式碼。

qdel 1250752

  執行上述程式碼,並在執行前後透過qstat命令檢視佇列中的任務,可以看到指定的任務已經被刪除了——但是有延遲:執行完qdel後立刻執行qstat的話,可以看到1250752這個任務還是在的;稍後再執行qstat,才可以看到1250752任務消失。

  任務執行完畢後,我們就可以依次執行下面的2句程式碼,開啟並檢視作業的標準輸出、錯誤輸出檔案。cat是一個常用的命令,用於連線指定的檔案,並列印它們的內容。

cat py_task.out
cat py_task.err

  執行上述程式碼,如下圖所示。當然,我這裡因為待執行的任務存有一些許可權上的錯誤,所以在py_task.err檔案中,給出了任務執行過程中的報錯內容。

  如果沒有錯誤的話,那麼大家就可以結合自己任務的實際情況,檢視任務執行的結果檔案了。

  至此,大功告成。

相關文章