ジョブ実行クラスターの振り分け

この文書では、ジョブの実行クラスターの振り分けを行うYAESSプラグイン asakusa-yaess-multidispatch の利用方法について解説します。

このプラグインを利用すると、個々のバッチやジョブフローなどを異なるクラスター上に振り分けて実行したり、それぞれ異なる設定で起動したりできるようになります。

クラスターの振り分け方法

このプラグインでは、バッチに含まれるそれぞれのジョブを実行する際に、それぞれ異なる設定を使ったジョブの実行が行えます。 バッチごとに異なる設定のクラスター上で処理を行ったり、ジョブフローごとに異なるHadoopパラメーターを利用するなど様々な設定が可能です。

このプラグインを利用する場合、YAESS本体の構成ファイルの hadoop セクション [1]command.<プロファイル名> セクション [2] に、専用のハンドラを登録します。 また、ハンドラの設定の中に、振り分け先のクラスター上でジョブを実行するような別のハンドラを複数登録します。 ここでは、このプラグインが提供するハンドラを「振り分けハンドラ」、振り分け先のハンドラのことを「サブハンドラ」と呼びます。

構成ファイルについての詳しい情報は、 Hadoopジョブの振り分け設定コマンドラインジョブの振り分け設定 をそれぞれ参照してください。

振り分ける規則は、「振り分け設定ファイル」というファイルを作成し、その中に記述します。 このファイルは対象のバッチごとに <バッチID>.properties というプロパティファイルとして作成します。

振り分け設定ファイル内には、ジョブフロー、フェーズ、ジョブがそれぞれどのサブハンドラを利用してジョブを起動するかを記載します。 振り分けハンドラは、振り分け設定ファイル内の情報をもとに、適切なサブハンドラを選択してそれぞれのジョブを実行します。

振り分け設定ファイルについての詳しい情報は、 ジョブの振り分け先設定 を参照してください。

[1]hadoop セクションについては YAESSユーザーガイド - Hadoopジョブの実行 を参照してください。
[2]command セクションについては YAESSユーザーガイド - コマンドラインジョブの実行 を参照してください。

プラグインの利用方法

プラグインの登録

このプラグインを利用するには、 asakusa-yaess-multidispatch というプラグインライブラリをYAESSに登録します。 このプラグインは バージョン 0.10.0 ではYAESSの標準構成に含まれています。

Hadoopジョブの振り分け設定

Hadoopジョブをサブハンドラに振り分けて実行する場合、構成ファイルの hadoop セクションに以下の内容を設定します。

Hadoopジョブの振り分け設定
名前
hadoop com.asakusafw.yaess.multidispatch.HadoopScriptHandlerDispatcher
hadoop.conf.directory 振り分け設定ファイルを配置するディレクトリ
hadoop.conf.setup setup フェーズを実行するサブハンドラ名
hadoop.conf.cleanup cleanup フェーズを実行するサブハンドラ名
hadoop.<サブハンドラ名> サブハンドラのクラス名
hadoop.<サブハンドラ名>.<設定名> サブハンドラの設定値

hadoop には振り分けハンドラを利用するためのディスパッチャクラスを指定します。 YAESS導入時には hadoop には標準的なハンドラクラスが設定されているので、この設定を変更します。

hadoop.conf.directory は振り分け設定ファイルを配置するディレクトリへの絶対パスを指定します。 このディレクトリの直下に対象バッチのバッチIDと同名の振り分け設定ファイルを作成し、それぞれのファイルで ジョブの振り分け先設定 を行います。

hadoop.conf.setuphadoop.conf.cleanup はいずれも省略可能です。 省略した場合は振り分け設定ファイルの内容を元にサブハンドラを選択します。 上記にサブハンドラ名を設定した場合、振り分け設定ファイルの内容によらず指定のサブハンドラで setup フェーズや cleanup フェーズのジョブをそれぞれ実行します。

hadoop.<サブハンドラ名>hadoop.<サブハンドラ名>.<設定名> では、サブハンドラの設定を行います。 ここでは、通常の hadoop セクションの代わりに hadoop.<サブハンドラ名> というサブセクションを作成し、それぞれのサブハンドラの設定を行ってください。 サブハンドラ名には半角の英数字のみを利用してください。

例えば、サブハンドラ名に remote を指定し、このハンドラに対して SSHを経由してHadoopジョブを実行する 設定を適用する場合、以下例のようになります [3]

yaess.properties
hadoop.remote = com.asakusafw.yaess.jsch.SshHadoopScriptHandler
hadoop.remote.ssh.user=asakusa
hadoop.remote.ssh.host=example.com
hadoop.remote.ssh.port=22

サブハンドラは複数定義することが出来ますが、必ず default という名前のサブハンドラの設定を含めてください。 これは、振り分け設定ファイルで振り分け先のサブハンドラが明示的に指定されなかった場合に利用されるサブハンドラとなります。

Attention

default という名前のサブハンドラが設定されていない場合、YAESSの初期化時にエラーとなります。

上記のうち、先頭の hadoop を除くすべての項目には ${変数名} という形式で、YAESSを起動した環境の環境変数を含められます。 ただし、サブハンドラについてはサブハンドラごとの設定項目によって環境変数を利用可能かどうかが決まります。

[3]ここでは設定の一部のみを記載しています。サブハンドラの設定については後述の 設定例 も参考にしてください。

コマンドラインジョブの振り分け設定

コマンドラインジョブをサブハンドラに振り分けて実行する場合、構成ファイルの command.<プロファイル名> セクションに以下の内容を設定します。

コマンドラインジョブの振り分け設定
名前
command.<プロファイル名> com.asakusafw.yaess.multidispatch.CommandScriptHandlerDispatcher
command.<プロファイル名>.conf.directory 振り分け設定ファイルを配置するディレクトリ
command.<プロファイル名>.conf.setup setup フェーズを実行するサブハンドラ名
command.<プロファイル名>.conf.cleanup cleanup フェーズを実行するサブハンドラ名
command.<プロファイル名>.<サブハンドラ名> サブハンドラのクラス名
command.<プロファイル名>.<サブハンドラ名>.<設定名> サブハンドラの設定値

command.<プロファイル名> には振り分けハンドラを利用するためのディスパッチャクラスを指定します。 YAESS導入時には command.<プロファイル名> には標準的なハンドラクラスが設定されているので、この設定を変更します。

command.<プロファイル名>.conf.directory は振り分け設定ファイルを配置するディレクトリへの絶対パスを指定します。 このディレクトリの直下に対象バッチのバッチIDと同名の振り分け設定ファイルを作成し、それぞれのファイルで ジョブの振り分け先設定 を行います。

command.<プロファイル名>.conf.setupcommand.<プロファイル名>.conf.cleanup はいずれも省略可能です。 省略した場合は振り分け設定ファイルの内容を元にサブハンドラを選択します。 上記にサブハンドラ名を設定した場合、振り分け設定ファイルの内容によらず指定のサブハンドラで setup フェーズや cleanup フェーズのジョブをそれぞれ実行します。

command.<プロファイル名>.<サブハンドラ名>command.<プロファイル名>.<サブハンドラ名>.<設定名> では、サブハンドラの設定を行います。 ここでは、通常の command.<プロファイル名> セクションの代わりに command.<プロファイル名>.<サブハンドラ名> というサブセクションを作成し、それぞれのサブハンドラの設定を行ってください。 サブハンドラ名には半角の英数字のみを利用してください。

例えば、サブハンドラ名に remote を指定し、このハンドラに対してコマンドラインジョブのプロファイル asakusa に対して SSHを経由してコマンドラインジョブを実行する 設定を適用する場合、以下のようになります [4]

yaess.properties
command.asakusa.remote = com.asakusafw.yaess.jsch.SshCommandScriptHandler
command.asakusa.remote.ssh.user=asakusa
command.asakusa.remote.ssh.host=example.com
command.asakusa.remote.ssh.port=22

Attention

コマンドラインジョブの振り分け機能を使うと、 コマンドラインジョブの実行 で説明するプロファイル単位で実行方法を切り替える機能の代替として、単一のプロファイル( command.* )のみを指定し、ジョブフロー単位でコマンドラインジョブを振り分けることで同様の振る舞いを実現可能な場合がありますが、この方法は推奨できません。

プロファイル単位で実行方法を分ける必要がある場合は、できるだけプロファイル名を分けて個別の command.<プロファイル名> セクションを用意して設定を切り替えるべきです。

サブハンドラは複数定義することが出来ますが、必ず default という名前のサブハンドラの設定を含めてください。 これは、振り分け設定ファイルで振り分け先のサブハンドラが明示的に指定されなかった場合に利用されるサブハンドラとなります。

Attention

default という名前のサブハンドラが設定されていない場合、YAESSの初期化時にエラーとなります。

上記のうち、先頭の command.<プロファイル名> を除くすべての項目には ${変数名} という形式で、YAESSを起動した環境の環境変数を含められます。 ただし、サブハンドラについてはサブハンドラごとの設定項目によって環境変数を利用可能かどうかが決まります。

[4]ここでは設定の一部のみを記載しています。サブハンドラの設定については後述の 設定例 も参考にしてください。

ジョブの振り分け先設定

ジョブをサブハンドラに振り分ける際には、「振り分け設定ファイル」を利用して振り分け先を判断します。

この振り分け設定ファイルは、 hadoop.conf.directorycommand.<プロファイル名>.conf.directory で指定したディレクトリの直下に <バッチID>.properties という名前で作成します [5]

振り分け設定ファイルには、以下のような行をJavaのプロパティファイルの形式で記載します。

ジョブの振り分け先設定
優先順位 行の内容 概要
1 <フローID>.<フェーズ名>.<ステージID> = <サブハンドラ名> 対象のジョブを指定のサブハンドラで実行する
2 <フローID>.<フェーズ名>.* = <サブハンドラ名> 対象フェーズ [6] のすべてのジョブを指定のサブハンドラで実行する
3 <フローID>.* = <サブハンドラ名> 対象ジョブフローのすべてのジョブを指定のサブハンドラで実行する
4 * = <サブハンドラ名> 対象バッチのすべてのジョブを指定のサブハンドラで実行する

一つの設定ファイルには複数の設定を記載することができます。 あるジョブの実行が2つ以上の設定に該当する場合、優先順位が最も小さい行に従います [7]

対応する振り分け設定ファイルが存在しない場合や、設定ファイル内にマッチする行が存在しない場合、 default という名前のサブハンドラを利用してジョブを実行します。

Attention

現在のAsakusa Frameworkでは、バッチコンパイルのたびにステージIDがランダムに決定されます。 ステージIDまで指定して設定を振り分ける場合にはアプリケーションの再デプロイの際に意図した設定が効かなくなる可能性があるため注意が必要です。

Hint

ステージIDについては、 Asakusa DSLユーザーガイド - Batch DSLコンパイラが生成するバッチアプリケーション を参照してください。

[5]例えばバッチIDが example.summarizeSales の場合、振り分け設定ファイル名は example.summarizeSales.properties となります。
[6]利用可能なフェーズについては YAESSユーザーガイド - Asakusa Frameworkのバッチ構造 を参照してください。 なお、 setupcleanup フェーズは振り分けハンドラ側の設定が優先されます。
[7]振り分け設定ファイル内に記載した行の順序は、設定の優先度に影響しません。

設定例

複数の実行環境にジョブフローを振り分ける例

以下はローカル環境上のHadoopの設定と、リモート環境上のHadopの設定を定義し、ジョブフロー単位で使用するHadoopを振り分ける設定例(構成ファイルの一部)です。 2つのHadoopクラスターを処理に応じて使い分ける場合などを想定しています。

ローカル環境上の設定に対するサブハンドラには default を、リモート環境の設定に対するサブハンドラには remote という名前をそれぞれ指定しています。

yaess.properties
# 振り分けハンドラ本体
hadoop = com.asakusafw.yaess.multidispatch.HadoopScriptHandlerDispatcher
hadoop.conf.directory = ${ASAKUSA_HOME}/yaess/conf/multidispatch/

command.* = com.asakusafw.yaess.multidispatch.CommandScriptHandlerDispatcher
command.*.conf.directory = ${ASAKUSA_HOME}/yaess/conf/multidispatch/

# ローカル環境向けサブハンドラ (default)
hadoop.default = com.asakusafw.yaess.basic.BasicHadoopScriptHandler
hadoop.default.resource = hadoop-local
hadoop.default.env.HADOOP_CMD = /usr/bin/hadoop
hadoop.default.env.ASAKUSA_HOME = ${ASAKUSA_HOME}

command.*.default = com.asakusafw.yaess.basic.BasicCommandScriptHandler
command.*.default.resource = asakusa-local
command.*.default.env.ASAKUSA_HOME = ${ASAKUSA_HOME}

# リモート環境向けサブハンドラ (remote)
hadoop.remote = com.asakusafw.yaess.jsch.SshHadoopScriptHandler
hadoop.remote.ssh.user=asakusa
hadoop.remote.ssh.host=example.com
hadoop.remote.ssh.port=22
hadoop.remote.ssh.privateKey=${HOME}/.ssh/id_dsa
hadoop.remote.resource = hadoop-remote
hadoop.remote.env.HADOOP_CMD = /usr/bin/hadoop
hadoop.remote.env.ASAKUSA_HOME = /home/asakusa/asakusafw

command.*.remote = com.asakusafw.yaess.jsch.SshCommandScriptHandler
command.*.remote.ssh.user=asakusa
command.*.remote.ssh.host=example.com
command.*.remote.ssh.port=22
command.*.remote.ssh.privateKey=${HOME}/.ssh/id_dsa
command.*.remote.resource = asakusa-remote
command.*.remote.env.ASAKUSA_HOME = /home/asakusa/asakusafw

そして、 md.batch というバッチに含まれる farexec というジョブフローのみをリモート環境で実行し、それ以外のすべての処理をローカル環境で動作させる場合を考えます。

まず、各 .conf.directory で指定したディレクトリ以下に、バッチ md.batch に対応する振り分け設定ファイルとして md.batch.properties というファイルを作成します。 上記の例では、 $ASAKUSA_HOME/yaess/conf/multidispatch/md.batch.properties というパスになります。 このファイルを以下のように定義します。

md.batch.properties
# farexec だけ remote で実行
farexec.* = remote

# それ以外は default で実行
* = default

Note

上記のように完全に異なる2つ以上の環境を併用する場合、ジョブフローまたはバッチの単位で振り分けを行うとよいでしょう。 フェーズやジョブなどジョブフローより細かい単位で振り分けを行った場合、ジョブフロー実行中の中間結果がジョブ間で共有されないため、通常は正しく動作しません。

なお、複数のクラスターでデフォルトのファイルシステムを共有している場合、上記は問題になりません。

単一の実行環境を異なる設定で利用する例

以下は同一のHadoopを異なる設定で利用する設定例(構成ファイルの一部)です。 振り分けの設定をチューニンパラメータとして利用する場合などを想定しています。

デフォルトの設定を利用するサブハンドラには default を、Reduceタスク数を4に設定したサブハンドラには reduce4 を、Reduceタスク数を8に設定したサブハンドラには reduce8 という名前をそれぞれ指定しています。

yaess.properties
# 振り分けハンドラ本体
hadoop = com.asakusafw.yaess.multidispatch.HadoopScriptHandlerDispatcher
hadoop.conf.directory = ${HOME}/.asakusa/multidispatch

# デフォルト設定を利用するサブハンドラ (default)
hadoop.default = com.asakusafw.yaess.basic.BasicHadoopScriptHandler
hadoop.default.resource = hadoop
hadoop.default.env.HADOOP_CMD = /usr/bin/hadoop
hadoop.default.env.ASAKUSA_HOME = ${ASAKUSA_HOME}

# 別の設定を利用するサブハンドラ (reduce4)
hadoop.reduce4 = com.asakusafw.yaess.basic.BasicHadoopScriptHandler
hadoop.reduce4.resource = hadoop
hadoop.reduce4.prop.mapred.reduce.tasks = 4
hadoop.reduce4.env.HADOOP_CMD = /usr/bin/hadoop
hadoop.reduce4.env.ASAKUSA_HOME = ${ASAKUSA_HOME}

# 別の設定を利用するサブハンドラ (reduce8)
hadoop.reduce8 = com.asakusafw.yaess.basic.BasicHadoopScriptHandler
hadoop.reduce8.resource = hadoop
hadoop.reduce8.prop.mapred.reduce.tasks = 8
hadoop.reduce8.env.HADOOP_CMD = /usr/bin/hadoop
hadoop.reduce8.env.ASAKUSA_HOME = ${ASAKUSA_HOME}

そして、 md.batch というバッチに含まれる medium というジョブフローの epilogue フェーズのみで mapred.reduce.tasks = 4 が有効になり、同ジョブフローのそれ以外のフェーズでは mapred.reduce.tasks = 8 が有効になるような例を考えます。

上記の例では、 $HOME/.asakusa/multidispatch/md.batch.properties というファイルを以下のように定義します。

md.batch.properties
medium.epilogue.* = reduce4
medium.* = reduce8

この場合、 medium.epilogue.* = reduce4 の方が medium.* = reduce8 よりも優先されるため、 epilogue フェーズではサブハンドラ reduce4 を利用します。 また、 それ以外のフェーズでは reduce8 を利用します。

なお、上記に記載されていないジョブフローでは、デフォルト設定の default を利用します。