ATLAS日本基礎ネットワーク LCGミドルウエアトレーニングコース

第三回 グリッドジョブ~グリッドを使う

ここでの目標

1.グリッドジョブの概要

1.1.共通のジョブ記述ファイルの使用

グリッドは全体で一つの仮想的な計算機と考えることが出来ます。しかしそれぞれのサイトは固有の資源、ハードウエア、OS、ソフトウエア等で構成されています。それ故、共通の言語(Job Description Language, JDL)で書かれたジョブリクエストをそれぞれのサイトの固有の制御情報に変換してジョブを実行させることになります。

JDLに使われる言語はClassAd (Classified Advertizement)言語というCondorプロジェクト(計算機クラスター制御のプロジェクト)で開発されたものを元にしています。ユーザはジョブをこのClassAdで記述することになります。

1.2.利用可能な計算資源の確認

ClassAdで書かれたジョブ要求は、リソースブローカ(RB)に問い合わせることにより、そこで実行が可能かどうかを確かめます。このときにランクをつけ、最もランクの高いところが最も実行に適しているということで、そのリソースブローカが管理するComputing Element(CE)にジョブ要求が渡されます。

ジョブ要求にはいろいろな条件を付けることが出来ます。CPUの速さが何GHz以上だとか、もちろんCPUの種類が何だとか、物理メモリーサイズが何MB以上だとか、あるいはOSがLinuxでディストリビューションはRHじゃないとだめとか。もちろんAtlasソフトウエアがインストールされていることなども条件になります。

RBが適切であると判定したCEにジョブが渡されますが、CEはさらに自分の傘下のワーカーノード(WN)にジョブを送ります。実際のジョブはWN上で実行されます。

1.3.必要なデータの用意

ジョブが投入される場所が決まったら、次に実行するプログラムを指定し、ジョブが実行できるだけの入力データの用意をする必要があります。

実行可能プログラムは元々OSやディストリビューションについてきているものでもインストール済みのソフトウエアでも、ユーザが自分で作ったものであってもその環境で動作するものであれば何でも構いません。この場合、ユーザのプログラムはそれが起動されるまでに適切な場所にインストールされなければなりません。これもジョブの一部として実行可能です。また、単一のイメージファイルであれば他の入力データファイルと同様にジョブ要求の中に記述することも可能です。

入力データの用意の仕方には主に二つの方法があります。ジョブ投入を行うローカルな場所にあるファイルをジョブ実行の前にグリッドジョブ投入の仕組みを使って転送する方法です。これはそのサイズがそれほど大きくないときに使用します。この方法で送られるファイルのセットをInputSandboxと呼びます。サイズの大きなファイルを入力として使う場合はカタログからローカルコピーを作ってからジョブを起動します。カタログから取ってくるデータファイルをInputDataとして記述することにより、そのデータが存在するSEの近くのCEが選ばれることになります。実際のローカルコピーの作成はジョブのステップの一部として別途記述する必要があります。

1.4.結果の回収

実行結果は標準出力、標準エラー出力も含めてファイルとして作られます。それ故、それらを回収する必要があります。入力データの場合と同様に、ファイルのセット(OutputSandboxと呼ばれる)としてジョブを投入したUIに戻す方法と、カタログに登録し実体をコピーしてどこからでも見えるようにする方法です。前者はファイルサイズが小さいとき、後者はファイルサイズが大きいときに使われるのが一般的ですが、小さいファイルをカタログすることも出来ます。あまり大きなファイルをOutputSandboxに載せることは出来ません。

2.ジョブの準備~JDLファイルを用意する

2.1.JDLファイルの文法

JDLの言語であるClassAdは単純な文法を持っています。

名前=値;

という表現の並びで構成されます。最後のセミコロンを忘れずに。

コメントは#で始まるか

# この部分はコメント

C++のコメントの書式を用います。

// この部分はコメント
/* この部分もコメント。
複数行にまたがることが出来る。*/

2.2.簡単なJDLファイルの用意

JDLファイルには必ず含まれていなければならない文があります。

Executable = 走らせるコマンド;
StdOutput = 出力ファイル名;
StdError = エラー出力ファイル名;

です。走らせるべきコマンドと、それが使用するであろう標準出力、標準エラー出力をリダイレクトするファイルです。これらの出力ファイルは当然回収されることを想定しています。例文としてはhostname.jdlとして次を編集しましょう。

Executable = "/bin/hostname";
StdOutput = "std.out";
StdError = "std.err";

2.3.output sandbox

このままでは出力が回収できません。ジョブはUIノードからRBノードを経由してWNノードに渡されます。WN上にstd.outやstd.errというファイルが出来ます。これらをUIノードまで戻してもらうためにOutputSandboxという文を記述します。

上のファイルhostname.jdlに次の行を追加します。

OutputSandbox = { "std.out","std.err" };

Executableで指定したコマンドの実行が完了したときにWNにあるこれらのファイルをUIまで転送してくれます。

これで、簡単ですがジョブを一つ記述しました。

3.ジョブを走らせることが出来るか確かめる~joblistmatch

次に、このJDLファイルを使ってジョブが走ることの出来るサイトを調べることにします。JDLの役割は、ジョブそのものの記述でもありますが、そのジョブをグリッド上のどこに投げるのが最適かを判定する情報としての役割もあります。マッチメーキング(お見合い?)と呼びますが、各地のRBに問い合わせて、そのジョブが走る条件を満たしているかどうか、どのくらい適切かを判断します。

$ glite-wms-job-list-match -a hostname.jdl
Selected Virtual Organisation name (from --vo option): atlas_j
Connecting to host dg03.cc.kek.jp, port 7772
***************************************************************************
                         COMPUTING ELEMENT IDs LIST
 The following CE(s) matching your job requirements have been found:
                   *CEId*
 dg01.cc.kek.jp:2119/jobmanager-lcgpbs-atlas_j
 dg06.cc.kek.jp:2119/jobmanager-lcgpbs-atlas_j
 gridtb02.icepp.jp:2119/jobmanager-lcgpbs-atlas_j
 lcg009.cc.kek.jp:2119/jobmanager-lcglsf-atlas_j
***************************************************************************

edg-job-list-matchコマンドは文字通り、マッチするCEをリストします。--vo atlas_j オプションでVOを指定しています。

VOのオプションによる設定は面倒ですが、VOMSへ登録されていない場合は必要です。

このジョブが実行可能なCEがいくつかあることがわかりました。

4.ジョブを走らせる~jobsubmit

次に、実際にジョブを投入しましょう。

$ glite-wms-job-submit -a -o jobid hostname.jdl
Selected Virtual Organisation name (from --vo option): atlas_j
Connecting to host dg03.cc.kek.jp, port 7772
Logging to host dg03.cc.kek.jp, port 9002
================================ edg-job-submit Success =====================================
 The job has been successfully submitted to the Network Server.
 Use edg-job-status command to check job current status. Your job identifier (edg_jobId) is:
 - https://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULg
 The edg_jobId has been saved in the following file:
 /home/sakamoto/tutorial/jobid
=============================================================================================

ジョブは無事に投入できました。実際にジョブを受け取ったRBはdg03.cc.kek.jpです。そこでhttps://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULgという名前が付けられました。これ以後、このジョブはこの名前で参照されます。とてもじゃないが覚えきれるものではないので-oオプションを使ってファイルにこの名前を書き出しました。jobidという名前のファイルがローカルに出来ています。

$ cat jobid
###Submitted Job Ids###
https://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULg

5.ジョブの状態を調べる~jobstatus

5.1.グリッドジョブの状態

これでグリッドジョブは投げられました。ジョブは次のような経過を経て完了に至ります。

これ以外にも

という状態を取り得ます。

5.2.状態を表示させる

実際に先ほど投げたジョブがどうなっているか見てみましょう。

$ glite-wms-job-status -i jobid
*************************************************************
BOOKKEEPING INFORMATION:
Status info for the Job : https://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULg
Current Status:     Done (Success)
Exit code:          0
Status Reason:      Job terminated successfully
Destination:        dg06.cc.kek.jp:2119/jobmanager-lcgpbs-atlas_j
reached on:         Wed Dec 14 03:21:33 2005
*************************************************************

説明をしている間に十分時間が経ったので完了しております。

6.ジョブの出力を取ってくる~jobgetoutput

6.1.ジョブの出力を取り出す

ジョブがDone状態になったら出力ファイルを取り寄せることが出来ます。

$ glite-wms-job-output -i jobid
Retrieving files from host: dg03.cc.kek.jp ( for https://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULg )
*********************************************************************************
                        JOB GET OUTPUT OUTCOME
 Output sandbox files for the job:
 - https://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULg
 have been successfully retrieved and stored in the directory:
 /tmp/jobOutput/sakamoto_3Cr_DwtAbSYSdLVEUPnULg
*********************************************************************************

ここにあるように、/tmp/jobOutputの下にディレクトリsakamoto_*が出来て、その中にOutputSandboxに書かれたファイルが置かれています。

6.2.取り出された結果を確認する

内容を確認してみましょう。

$ ls -l /tmp/jobOutput/sakamoto*
total 4
-rw-r--r--    1 sakamoto jst             0 Dec 14 06:53 std.err
-rw-r--r--    1 sakamoto jst            16 Dec 14 06:53 std.out

ちゃんとstd.outとstd.errが出来ています。std.errのサイズが0なので、stderrへは何も書かれなかったことがわかります。

std.outの内容を確認しましょう。

$ cat /tmp/jobOutput/sakamoto_3Cr_DwtAbSYSdLVEUPnULg/std.out
wn35.kekgrid.jp

wn35.kekgrid.jpと表示されました。/bin/hostnameの出力ですが、wn35.kekgrid.jpで実行されたことがわかります。(このホストアドレスはKEKのプライベートネットワークのものです)

6.3.後始末

ジョブ出力を取り出した後なので

$ glite-wms-job-status -i jobid
*************************************************************
BOOKKEEPING INFORMATION:
Status info for the Job : https://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULg
Current Status:     Cleared
Status Reason:      user retrieved output sandbox
Destination:        dg06.cc.kek.jp:2119/jobmanager-lcgpbs-atlas_j
reached on:         Wed Dec 14 06:53:44 2005
*************************************************************

という結果になります。

必要がなければUI上のファイルも消去します。

$ rm -rf /tmp/jobOutput/sakamoto*

作業場所に作ってしまったjobidというファイルも消しておきましょう。

$ rm jobid

7.より実際的なJDL

7.1.シェルスクリプトをジョブとして走らせる

実際のジョブでは、いろいろな環境変数を設定したり、ジョブステップを分けて段階毎に処理を行うようにします。そのため、実行イメージとしてはジョブスクリプトを走らせることにするのが一般的です。

シェルスクリプトを走らせるJDLを書いておきましょう。testenv.shというスクリプトファイルを走らせることにします。testenv.jdlというファイルを作ります。

[
Executable = "/bin/sh";
Arguments = "testenv.sh";
StdOutput = "std.out";
StdError = "std.err";
InputSandbox = {"testenv.sh"};
OutputSandbox = {"std.out","std.err"};
]

JDLの文法に従い、ここではジョブ範囲を[]で囲ってあります。

実行可能イメージとして/bin/shを選びました。それに対し、引数を与えます。これがtestenv.shというシェルスクリプトと言うことになります。出力は同じままにしておきます。このtestenv.shはユーザがUI上に用意するものなので、WNに送る必要があります。それ故、InputSandbox文を追加しました。

7.2.グリッド上のジョブ動作環境を確認するためのシェルスクリプトを用意する

次にこのtestenv.shを用意しなければなりません。実際には任意のスクリプトを書けばよいのですが、ここでは実際にWNの環境がどんなものかを調べるために次のようなものを書いてみます。

#!/bin/sh
echo "Current working directory --"
pwd
echo "Contents of this directory --"
ls -al
echo "Contents of /--"
ls -l /
echo "Contents of /opt--"
ls -l /opt
echo "Contents of /opt/exp_soft--"
ls -l /opt/exp_soft
echo "Contents of /opt/exp_soft/atlas_j--"
ls -l /opt/exp_soft/atlas_j
echo "df--"
/bin/df
echo "gcc--"
/usr/bin/which gcc
echo "gcc vresion--"
gcc --version
echo "environments--"
/usr/bin/printenv

それぞれの行の意味は自明でしょう。/opt/exp_softを見ているのは、実験固有のソフトウエアのインストール場所がVO毎に設定されるからです。/opt/exp_soft/atlas_jの下に、athena関係などのソフトウエアがインストールされているはずです。それを確認しています。

これ自身実行できるようにモードを変えておきましょう。

$ chmod 755 testenv.sh

試しにローカルに走らせてみてください。問題ないでしょうか。

$ ./testenv.sh

もし、綴り間違いなどがあれば訂正しておきます。

7.3.環境確認ジョブを走らせる

これでジョブの用意が出来ました。先ほどと同様にジョブを投入します。

$ glite-wms-job-submit --vo atlas_j -o jobid testenv.jdl

実行結果を得るため

$ glite-wms-job-status -i jobid
$ glite-wms-job-output -i jobid

得られた標準出力の内容を確認しましょう。

8.ジョブを走らせる条件を指定する

JDLへの条件の記述

joblistmatchでの確認

CEを指定してジョブを投げる

9.直接CEにジョブを投げる~globus-job-run

RBを経由せずにジョブを投げる

テストのために使用



2009年12月6日更新