連載
» 2013年12月25日 18時00分 公開

OSS「JobScheduler」で実現するこれからの運用自動化(3):排他制御などを活用して複雑なジョブ定義だってOK (2/3)

[船井覚,@IT]

複雑なジョブの設定方法

 それでは基本編で説明した機能を踏まえつつ、実際のジョブ管理に必要な設定方法を紹介していきましょう。

多重実行と排他制御の活用

 実際の運用においては、「複数のジョブを同時多重で実行させたいが、リソースの関係で、あるジョブだけは同時実行数を制限したい」といった要件がよくあると思います。このとき、同じジョブを異なるパラメーターで実行することもあるでしょうし、全く異なるジョブを多重実行させることもあるでしょう。

 JobSchedulerは、ジョブ単位での排他制御と待ち合わせ制御の機能を備えており、このような要件に応じた制御も可能です。

図4 複雑なジョブ制御の例

 この例では、ジョブ1がジョブ2-1〜2-3を同時起動します。ただし、ジョブ2-3だけは単独実行させたいとします。また、ジョブ2-1〜2-3の全てが完了してから、ジョブ3を起動することとします。

 これをJobSchedulerで制御する場合、次のように2つのJob Chainを組み合わせて定義します。

図5 図4のジョブをJobSchedulerで制御するときの定義

 図5に示す「ParallelSample」は、メイン処理のJob Chainです。これを実行すると全てのジョブが実行されます。

 「ParallelExecution」は、ParallelSampleのexecuteジョブから内部APIを使用して実行するJob Chainです。各ジョブに3パターンのstateを定義して、処理の流れを制御します。Syncジョブは、イベントを使用して複数のジョブの待ち合わせを制御します。

JOEを用いたSyncジョブの定義

 最初にSyncジョブの定義を作成します。エディターから直接XMLファイルを作成して定義することもできますが、ここではJOEを使用します。

 JOEのFileメニューから[New]→[HotFolderObject]→[Job]を選択します。

図6 JOEの設定画面

 Job Nameを入力し、Languageでは「Java」を選択します。Classnameは、待ち合わせを行う内部APIのsos.scheduler.job.JobSchedulerSynchronizeJobChainsを入力します。

図7

 Optionタブを選択し、Job Chain jobのYesを選択します。

図8

 左側メニューのParameterを選択し、Newボタンをクリック、ParameterのNameとValueを入力しApplyをクリックします。

図9

 同期対象とするOrderを指定するために、「[Job Chain名]_required_orders」という形式で特定のJob Chainを指定し、同期させたいOrder数を指定します。特に設定しなければ、同じホットフォルダ内でSync Job Chainsを定義したJob ChainのOrderが、全て同期対象になります。

 今回は、ParallelExecutionで3回、ParallelSampleで1回Orderを実行しますので、ParallelExecution_required_ordersを「3」、ParallelSample_required_ordersには「1」と入力し、保存します。

 保存されたXMLファイルを開くと、下記のような内容になっています。

<?xml version="1.0" encoding="ISO-8859-1"?>
<job  order="yes" tasks="1" name="Sync">
    <description >
        <include  file="jobs/JobSchedulerSynchronizeJobChains.xml"/>
    </description>
    <params >
        <param  name="ParallelExecution_required_orders" value="3"/>
        <param  name="ParallelSample_required_orders" value="1"/>
    </params>
    <script  language="java" java_class="sos.scheduler.job.JobSchedulerSynchronizeJobChains" java_class_path=""/>
    <run_time />
</job>

executeジョブの定義

 次に、executeジョブの定義を作成します。

 executeジョブは、ParallelExcution Job Chainを実行するOrderを生成するジョブです。同一のジョブ定義で、毎回異なるジョブを実行するOrderを生成するために、sos.scheduler.managed.configuration.ConfigurationOrderMonitorという、Orderのパラメーターを制御する内部APIを使用します。

図10

 図10では、1回目のexecuteジョブを「state=p1」とし、パラメーターとして「state=p1」を設定した「order p1:1」を発行します。以降、2回目、3回目も「同じジョブ、同じorderで、異なるstateのパラメーター」を指定したorderを発行することで、ParallelExecution Job Chainのそれぞれに対応するジョブを実行させます。

 executeジョブの役割は、Orderを生成・実行するだけで、Orderの実行が完了するまで待機することはありません。

 では、この部分を定義していきましょう。JOEで新規ジョブを作成し、Job Nameに「execute」と入力します。Languageは「java:javascript」を選択します(注)。

図11

注:JobScheduler 1.5から、64ビットJavaに対応した64ビット版も提供されることになり、これに伴いJavaScriptエンジンも、32ビット版の「Spider Monkey」から64ビット版の「Rhino」に変更になりました。64ビット版JobSchedulerを使用する場合は「java:javascript」を選択し、32ビット版を使用する場合は「javascript」を選択してください。


 次に、ScriptタブのExecutableに、以下のJavaScriptコードを入力します。

function spooler_process(){
   var actOrder = spooler_task.order;
   var order = spooler.create_order();
   var job_chain = spooler.job_chain(spooler_task.params.value("job_chain"));
   order.state = actOrder.state;
   order.params.merge(actOrder.params);
   order.id = order.state + ":" + actOrder.id;
   job_chain.add_or_replace_order(order);   
   return true;
}

 コードの示す内容は、以下の通りです。

コード 処理内容
spooler_process trueが返り値の場合、Next_stateのNodeにOrderを進めます
spooler_task.order 処理中のOrderを返します
spooler.create_order Orderを作成します
spooler.job_chain Job Chain名を返します
job_chain.add_or_replace_order Job ChainにOrderを追加し、もし同じOrder IDがあれば上書きします

 Optionsタブを選択し、Job Chain JobをYesに変更します。

図12

 次に、JavaScriptのコードで定義した変数“job_chain”をパラメーターとして定義します。

 左側のメニューから「Parameter」を選択し、「New」をクリックします。Nameに「job_chain」、Valueには、executeジョブからorderを発行するJob Chainのパス(ここでは「/SampleParallel/ParallelExecution」)を入力し、Applyをクリックします。

図13

 最後に、Orderにパラメーターを渡すための内部APIを設定します。左側のメニューから「Pre-/Post-Processing」を選択し、「New」をクリックします。Nameに「configuration_monitor」と入力し、Languageは「Java」を選択、Classnameに「sos.scheduler.managed.configuration.ConfigurationOrderMonitor」と入力し、ファイルを保存します。

図14

 保存されたXMLファイルを開くと、下記の内容になっているはずです。

<?xml version="1.0" encoding="ISO-8859-1"?>
<job  order="yes" stop_on_error="no" tasks="3" name="execute">
    <params >
        <param  name="job_chain" value="/SampleParallel/ParallelExecution"/>
    </params>
    <script  language="java:javascript">
        <![CDATA[
function spooler_process(){
   var actOrder = spooler_task.order;
   var order = spooler.create_order();
   var job_chain = spooler.job_chain(spooler_task.params.value("job_chain"));
   order.state = actOrder.state;
   order.params.merge(actOrder.params);
   order.id = order.state + ":" + actOrder.id;
   job_chain.add_or_replace_order(order);   
   return true;
}
        ]]>
    </script>
    <monitor  name="configuration_monitor">
        <script  java_class="sos.scheduler.managed.configuration.ConfigurationOrderMonitor" language="java" java_class_path=""/>
    </monitor>
    <run_time />
</job>

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。