====== torque (旧OpenPBS) ======
===== 概要 =====
* 計算機クラスターのジョブ管理スケジューラ
* 異なるジョブを逐次処理させたい場合に便利 (以下の条件の時とか?)
* メモリや CPU を最大まで使うジョブが複数あり、同時に流すとリソースの取り合いになる。最悪の場合、計算機が落ちる。
* コマンドラインで、 && とか ; で複数のジョブをつなげても実現できるけど、その後に追加のジョブが入った場合は?
* ジョブの終了時間を予測し、マージンをとって、at コマンドで時間を指定してジョブを実行する方法もあるけど、マージン分の時間がもったいない。予測が外れたらリソースの取り合いになる。
* 要はプリンターの印刷状況画面のキュー (印刷データ) が、ジョブに置き換わっただけ。
* 別に計算機クラスターである必要はなく、自分の PC に入れても問題ない
* Ubuntu (Debianも?)では、torque-server (サーバ用)、torque-scheduler (スケジューラ)、torque-mom (ノード用) の 3 つのパッケージで機能する
* スケジューラを変えるなどすることもあるようだ
===== 導入方法 =====
==== サーバ側(サーバでもジョブを処理させる場合) ====
- インストール
* サーバでもジョブを処理させる場合 \\ $ sudo apt-get install torque-server torque-mom torque-client torque-scheduler
- 起動中の torque を終了させる
- 起動中の torque を確認\\ $ ps -e | grep pbs
- root 権限で終了させる (service コマンドの stop や kill) する\\
$ sudo service torque-mom stop
$ sudo service torque-scheduler stop
$ sudo service torque-server stop
※service コマンドで torque-server が終了しない場合\\ $ sudo kill 24277
24277 は、pbs_server の PID で ''ps -e | grep pbs'' で確認する
- 設定ディレクトリの設定\\
$ sudo mkdir /var/spool/torque/server_priv
$ sudo chmod 777 /var/spool/torque/spool /var/spool/torque/undelivered
$ sudo chmod o+t /var/spool/torque/spool /var/spool/torque/undelivered
- サーバ名の設定\\ $ sudoedit /etc/torque/server_name
ホスト名を入れる
- 新たにサーバプロファイルを作成 (このコマンドを実行すると torque_server が起動する)\\ $ sudo pbs_server -t create
- ノードの設定\\
$ ps -e | grep pbs
$ sudo kill xxxxx
$ sudoedit /var/spool/torque/server_priv/nodes
* 中には ''__ノード名__ np=__CPU数__'' を列挙していく
* 例:\\
server np=8
node1 np=4
node2 np=4
node3 np=2
- ホスト名の設定\\ $ sudoedit /etc/hosts
* 127.0.0.1 は localhost からホスト名に変更
* 127.0.1.1 はコメントアウト
* ノードのホスト名も入れていく
- サーバやキューの設定 (設定ファイルを読み込ませる)\\
$ sudo service torque-server start
$ sudo qmgr < queue.conf
* 設定ファイル (queue.conf) は以下の通り\\
#
# Create queues and set their attributes.
#
#
# Create and define queue F
#
create queue F
set queue F queue_type = Execution
set queue F resources_default.ncpus = 1
set queue F resources_default.nodes = 1
set queue F enabled = True
set queue F started = True
#
# Create and define queue Q2
#
create queue Q2
set queue Q2 queue_type = Execution
set queue Q2 max_running = 1
set queue Q2 resources_max.ncpus = 4
set queue Q2 resources_max.nodes = 1
set queue Q2 resources_default.ncpus = 1
set queue Q2 resources_default.nodes = 1
set queue Q2 resources_available.ncpus = 4
set queue Q2 resources_available.nodes = 1
set queue Q2 enabled = True
set queue Q2 started = True
#
# Create and define queue Q4
#
create queue Q4
set queue Q4 queue_type = Execution
set queue Q4 max_running = 1
set queue Q4 resources_max.ncpus = 4
set queue Q4 resources_max.nodes = 1
set queue Q4 resources_default.ncpus = 1
set queue Q4 resources_default.nodes = 1
set queue Q4 resources_available.ncpus = 4
set queue Q4 resources_available.nodes = 1
set queue Q4 enabled = True
set queue Q4 started = True
#
# Create and define queue Q1
#
create queue Q1
set queue Q1 queue_type = Execution
set queue Q1 max_running = 1
set queue Q1 resources_max.ncpus = 4
set queue Q1 resources_max.nodes = 1
set queue Q1 resources_default.ncpus = 1
set queue Q1 resources_default.nodes = 1
set queue Q1 resources_available.ncpus = 4
set queue Q1 resources_available.nodes = 1
set queue Q1 enabled = True
set queue Q1 started = True
#
# Create and define queue Q3
#
create queue Q3
set queue Q3 queue_type = Execution
set queue Q3 max_running = 1
set queue Q3 resources_max.ncpus = 4
set queue Q3 resources_max.nodes = 1
set queue Q3 resources_default.ncpus = 1
set queue Q3 resources_default.nodes = 1
set queue Q3 resources_available.ncpus = 4
set queue Q3 resources_available.nodes = 1
set queue Q3 enabled = True
set queue Q3 started = True
#
# Set server attributes.
#
set server scheduling = True
set server default_queue = F
set server log_events = 511
set server query_other_jobs = True
set server scheduler_iteration = 600
set server node_check_rate = 150
set server tcp_timeout = 6
set server node_pack = False
set server allow_node_submit = True
* F: 制限がないキュー
* Q1〜Q4: 1 ジョブしか流せないキュー
- 起動\\
$ sudo service torque-scheduler start
$ sudo service torque-mom start
- サーバ名の確認\\ $ qstat -q
- サーバの設定状況の確認\\ $ pbsnodes -a
- テスト\\
$ echo "sleep 30" | qsub
$ qstat
==== サーバ側 (サーバでジョブを処理させない場合) ====
- インストール \\ $ sudo apt-get install torque-server torque-scheduler
==== ノード側 ====
- インストール\\ $ sudo apt-get install torque-mom torque-client
===== 使い方 =====
* ジョブ投入\\ $ qsub [オプション] ジョブファイル
Job id Name User Time Use S Queue
------------------------- ---------------- --------------- -------- - -----
760.servername JOB_NAME1 hoge 311:35:2 R F
762.servername JOB_NAME2 hoge 165:50:2 R F
860.servername JOB_NAME3 fuga 03:03:40 R F
* Job id: 投入順に番号が付けられる (job id を指定するコマンドでは、最初の数字だけで十分)
* Name: ジョブ名
* qsub の -N オプションや、ジョブファイルの PBS -N で指定が可能
* オプションなどで指定されていない場合は、ジョブファイル名の先頭から15文字が使われる
* User: ジョブを投入したユーザ名
* Time: ジョブ処理にかかっている時間 (複数の CPU を指定している場合は、CPU 数に合わせて倍になる)
* S: ステータス
* R: Running (処理中)
* Q: Queue (待機中)
* H: Hold (保留中; ジョブの順番が回ってきても処理しない)
* E: Exit (終了; ?)
* T: 移行中(?)
* W: 待機中(?)
* Queue: ジョブが所属しているキュー
* ジョブ一覧\\ $ qstat [オプション]
* ジョブ削除\\ $ qdel ジョブID ...
* ジョブIDは複数指定が可能
* ジョブの順序の入れ替え\\ $ qorder ジョブID1 ジョブID2
* ジョブの保留(ジョブ実行の順番が回ってきても実行しない) \\ $ qhold ジョブID1 ジョブID2 ...
* ジョブの保留解除\\ $ qrls ジョブID1 ジョブID2 ...
* ジョブの実行\\ $ qrun ジョブID1 ジョブID2 ...
* キューの変更\\ $ qmove 変更後のキュー名 ジョブID
* ジョブにシグナルを送信\\ $ qsig -s シグナル ジョブID
* STOP: ジョブのサスペンド(ジョブを停止することなく、CPU を空ける; ただし、torque としては CPU が空くわけではないので、次のジョブは実行されない)
* CONT: サスペンドしたジョブの再開
===== ジョブファイル =====
* ジョブの内容を書いたシェルスクリプト
* シバン行 (#!/bin/bash など) に続いて、''#PBS ...'' で始まるジョブ指定
* 例 (bash ベースの場合): \\
#!/bin/bash
#PBS -V
#PBS -l nodes=1:ppn=4
#PBS -j oe
#PBS -N jobname
cd ${PBS_O_WORKDIR}
実行コマンド
:
* ${PBS_O_WORKDIR}: torque が利用する作業ディレクトリ (必ず書く必要がある)
* オプション (qsub のオプションと同じ)
^ オプション ^ 意味 ^ 値 ^
|-V|ジョブを投入した所の環境変数をすべて、ジョブファイルにも適用する| |
|-v|ジョブを投入した所の環境変数を指定した分だけ、ジョブファイルにも適用する| |
|-q|キューの指定| |
|-j|出力ファイルの制御|oe: 標準出力と標準エラーを標準ファイル(*.o__ジョブID__)にまとめる, eo: 標準出力と標準エラーを標準エラーファイル(*.e__ジョブID__)にまとめる, 指定しない場合は、それぞれのファイルが出力される|
|-o|標準出力ファイルのパス| |
|-e|標準エラーファイルのパス| |
|-m|メール送信の方法|次の文字の組み合わせでメールの送信タイミングを指定 a: ジョブが失敗, b: ジョブが開始, e: ジョブが終了, n: 何もしない|
|-M|メールの送信先| |
|-l|リソースの指定(複数ある場合は、カンマで区切る)|walltime=__24:00:00__|
|:::|:::|nodes=__2__:ppn=__2__ (2CPUずつ2ノードを使う; 計4CPU)|
|:::|:::|nodes=__ノード1__:ppn=__3__+__ノード2__:ppn=__2__+__ノード3__:ppn=__1__ (特定のノードを利用する場合はノード名を書いて + で結合する)|
|:::|:::|mem, ncpu が使える|
|-N|ジョブ名|指定しない場合は、ジョブファイル名の先頭から15文字|
===== キューの設定項目 =====
==== サーバ設定 ====
''set server ...'' で始まる項目
^ 項目 ^ 意味 ^ 値 (太字がデフォルト) ^
|scheduling|スケジューリングの有効化|true or false|
|default_queue|デフォルトのキューを設定| |
|log_events|ログの出力内容| |
|query_other_jobs|root以外のユーザが他人のジョブを閲覧する許可|true or **false**|
|scheduler_iteration|?| |
|node_check_rate|ノードが死亡していると判断するまでの時間(秒)|整数値 (**600**)|
|tcp_timeout|pbs_serverとpbs_mon間のTCPソケットのタイムアウト時間(秒)|整数値 (**8**)|
|node_pack|1つのノードを埋めてから次のノードを利用するか|true or false|
|allow_node_submit|ノードからのジョブ投入の許可|true or **false**|
=== キュー設定 ===
''set queue キュー名 ...'' で始まる項目
^ 項目 ^ 意味 ^ 値 (太字がデフォルト) ^
|queue_type|キュータイプ| execution(e) or route%%(r)%%|
|resource_default.ncpus|デフォルトで指定されるCPU数| |
|resources_default.nodes|デフォルトで指定されるノード数| |
|enabled|ジョブの受け入れ(このキューでのジョブ投入を許可するか)|true or **false**|
|started|ジョブを実行するか(falseならhold状態で投入される)|true or **false**|
===== その他 =====
* qmgr の設定を表示\\ $ echo 'p s' | sudo qmgr
* '''p s''' は '''print server''' でも可
* 長時間ジョブを別々のキューで走らせた時に後方にある一方のキューが動かない
* 例:
- CPU が 2 つある計算機上で、CPU を 1 つのみ使い、1 つずつしか走らせることができないキュー A, B にジョブを 3 つずつ投入する予定である (計6ジョブ)
* ジョブ A1, A2, A3
* ジョブ B1, B2, B3
* それぞれのジョブは 25 時間以上かかるものとする
- 先にキュー A に 3 ジョブ (A1, A2, A3) 投入する (CPU は 1 つしか使っていない状態)
- 25時間後に、キュー B の 3 ジョブ (B1, B2, B3) を投入する (本来ならば、キュー B のジョブの処理がすぐに開始されるはず…)
- なぜか、キュー B のジョブが開始しない
* 原因: starving job 機構
* ジョブスケジューラはジョブの処理数を上げるため、指定された walltime が短いジョブから順に処理していく。
* しかし、これだと walltime が長いジョブは、短いジョブが後から次々と投入されると、一向に処理されない状態になる
* これを解決するために、starving job 機構があり、待機状態にあるジョブ (walltime が長いジョブ) が一定時間超えると、そのジョブを優先的に処理しようとする。
* torque の starving job 機構のデフォルトの設定時間は 24 時間
* 例で示した場合、A1 の処理中に 24 時間が経過し、A2, A3 が優先的に処理されるように設定されるが、キュー A はそもそも同時に 1 つしか処理できないため、CPU が 1 つ空いたまま、B1, B2, B3 は待機状態となる。
* キューに使用 CPU や同時ジョブ処理数の制限がかかっていると、例のような問題が起こる
* 解決方法 (/var/spool/torque/sched_priv/sched_config の編集)
* starving job 機構の無効化
* ''help_starving_jobs true ALL'' の true を false に変える
* 機構が有効になるまでの時間の変更
* ''max_starve: 24:00:00'' の時間を長くする
* job starving 機構の問題の見分け方
* ''$ qstat -f'' でジョブ状態を表示し、その中に ''comment = Not Running: Draining system to allow starving job to run'' とあれば、この問題でジョブが処理されないことになる。
===== 参考サイト =====
* [[http://tech.ckme.co.jp/torque.shtml | TORQUEの導入・設定:tech.ckme.co.jp]] インストールなど
* [[http://docs.adaptivecomputing.com/torque/4-0-2/Content/topics/4-serverPolicies/queueAttributes.htm | Queue attributes]] qmgr キューの設定
* [[http://docs.adaptivecomputing.com/torque/3-0-5/a.bserverparameters.php | ]] qmgr サーバ設定
* [[http://wiki.epii.jp/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2/TORQUE | ソフトウェア/TORQUE - epii's Wiki]] qmgr サーバ設定
* [[http://www.nas.nasa.gov/hecc/support/kb/commonly-used-qsub-options-in-pbs-scripts-or-in-the-qsub-command-line_175.html | Commonly Used QSUB Options in PBS Scripts or in the QSUB Command Line - HECC Knowledge Base]] ジョブファイルオプション