Asakusa FrameworkのWindGate SSHのメモ。
|
WindGateはRDB(やローカルファイル)と連携するコンポーネント。
よくある構成ではAsakusaアプリケーション(WindGateを含む)をHadoopクラスター(たいていはマスターノード)に配置し、そこからYAESSを使って起動する。
DBサーバー | Hadoopクラスター | |||
---|---|---|---|---|
RDB | ←(JDBC)→ | Asakusaアプリ (WindGate) |
←→ | HDFS |
↑ YAESS |
しかしRDBとHadoopクラスターとの直接接続(通信)が出来ない(許可されない)環境も有り得る。
そうした場合、RDBと通信を行う機能(つまりWindGate)を別サーバーに出すという構成にすることが出来る。
この構成では、RDBとWindGate間はJDBC、WindGateとHadoopクラスター間はSSHを使ってデータ転送される。
DBサーバー | WindGateサーバー | Hadoopクラスター | ||
---|---|---|---|---|
RDB | ←(JDBC)→ | WindGate (Asakusaアプリ) |
←(SSH)→ | HDFS |
↑ YAESS |
→(SSH)→ | Asakusaアプリ |
この構成の場合、Asakusaアプリ(ASAKUSA_HOME配下一式)をWindGateサーバーとHadoopクラスター(マスターノード)の両方に配置しておく必要がある。
そして、WindGateのプロファイルにRDBへ接続する為のJDBCの設定と、HadoopクラスターにSSH接続する為の設定をする。
また、YAESSもHadoopクラスター(マスターノード)にSSHで入ってhadoopコマンドを実行するので、SSH接続の設定が必要となる。
例として、WindGateサーバー上のローカルファイル(CSVファイル)を読み込んでHDFS上にCSVファイルとして書き込むアプリケーション・構成を作ってみる。
(RDBを用意するのは面倒なので、ローカルファイル読み込みとする。RDBの場合は、DMDLに付ける属性やImporter記述およびWindGateプロファイルの内容が異なるだけ)
Asakusaアプリケーションの起動(YAESSのシェルの実行)はWindGateサーバー上で行う。
WindGateサーバー | Hadoopクラスター | |||
---|---|---|---|---|
ローカルファイル | → | WindGate (Asakusaアプリ) |
→(SSH)→ | HDFS |
↑ YAESS |
→(SSH)→ | Asakusaアプリ |
WindGateサーバー上では「asakusa」というユーザーでAsakusaアプリケーション一式(WindGateやYAESSを含む)を扱うものとする。
Hadoopクラスター上では「hadoop」というユーザーでHadoopの操作およびAsakusaアプリケーション一式の配置を行うものとする。
サーバー | ホスト名 | ディレクトリー | 説明 |
---|---|---|---|
WindGateサーバー | hishidama-gateway | /home/asakusa/asakusa |
Asakusaアプリケーション |
/home/asakusa/.ssh |
SSH設定 | ||
/home/hadoop |
Hadoop | ||
Hadoopクラスター(マスターノード) | hishidama-hadoop | /home/hadoop |
Hadoop |
/home/hadoop/.ssh |
SSH設定 | ||
/home/hadoop/asakusa |
Asakusaアプリケーション |
AsakusaFWのバージョンは0.6.1、Linux上でGradleプラグインを使ってAsakusaアプリケーションを開発する想定。
今回の例では、WindGateサーバーのホスト名を「hishidama-gateway」、Hadoopクラスターのマスターノードのホスト名を「hishidama-hadoop」とする。
実験するだけであれば、Hadoopクラスターはスタンドアローンでよい(仮想分散にもする必要は無い)。
WindGateサーバーとマスターノードの/etc/hostsを設定しておく。
192.168.1.23 hishidama-hadoop 192.168.1.24 hishidama-gateway
Hadoopクラスターには当然Hadoopをインストールしておく。
WindGateサーバーにもHadoopをインストールする必要がある。
これは、シーケンスファイルを扱うライブラリー(jarファイル)を使用する為らしい。[2014-04-01]
(なお、例えばHadoopクラスター側がMapRの場合、WindGateサーバーにインストールするHadoopはMapRである必要は無く、MapRのベースとなるHadoopバージョン(1.0.3とか)と一致するApache
Hadoopであれば良いらしい)
今回の例では、WindGateサーバーとHadoopクラスターの両方とも「/home/hadoop」にHadoopをインストールしてあるものとする。
すなわち、hadoopコマンドの場所(環境変数HADOOP_CMD)は/home/hadoop/bin/hadoopとなる。
WindGateサーバーからHadoopクラスター(マスターノード)にSSH通信できる必要がある為、SSHの設定を行う。
$ cd /home/asakusa $ mkdir .ssh $ chmod 700 .ssh
$ ssh-keygen -t dsa Generating public/private dsa key pair. Enter file in which to save the key (/home/asakusa/.ssh/id_dsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/asakusa/.ssh/id_dsa. Your public key has been saved in /home/asakusa/.ssh/id_dsa.pub. 〜 $ ls id_dsa id_dsa.pub
$ cd /home/hadoop $ mkdir .ssh $ chmod 700 .ssh
$ cd /home/hadoop/.ssh $ cat id_dsa.pub >> authorized_keys $ chmod 600 authorized_keys
$ ssh -i /home/asakusa/.ssh/id_dsa hadoop@hishidama-hadoopキー生成時に設定したパスワードを入力して、接続できればOK。
今回の例では、WindGateを使ってローカルのCSVファイルを読み込み、その内容をそのままDirect I/OでHDFS上にCSVファイルを書き込む。
つまり、ImporterはWindGate、ExporterはDirect I/Oになる。
どちらもCSVファイルなので、データモデル定義(DMDL)では@windgate.csvと@directio.csvを指定する。
(RDBを入力とする場合は、@windgate.csvの代わりに@windgate.jdbcを指定する)
@windgate.csv @directio.csv example_model = { text1 : TEXT; text2 : TEXT; };
package com.example.batchapp.jobflow; import com.example.modelgen.dmdl.csv.AbstractExampleModelCsvImporterDescription; public class ExampleModelFromLocalCsv extends AbstractExampleModelCsvImporterDescription { @Override public String getProfileName() { return "gateway"; } @Override public String getPath() { return "input/example.csv"; } @Override public DataSize getDataSize() { return DataSize.LARGE; } }
今回のImporterはWindGateなので、プロファイルを定義する必要がある。今回のプロファイル名は「gateway」としてある。
(RDBから読み込む場合は、RDB用のImporterを作る。ファイルのパスの代わりにテーブル名とかSELECT文のWHERE条件とかを書く)
package com.example.batchapp.jobflow; import com.example.modelgen.dmdl.csv.AbstractExampleModelCsvOutputDescription; import java.util.List; public class ExampleModelToHdfsCsv extends AbstractExampleModelCsvOutputDescription { @Override public String getBasePath() { return "hadoop"; } @Override public String getResourcePattern() { return "output/example*.csv"; } }
今回のExporterはDirect I/Oなので、ベースパスを定義する必要がある。今回のベースパスは「hadoop」としてある。
(これが具体的にどのディレクトリーを指すのかは、core/conf/asakusa-resources.xmlのcom.asakusafw.directio.〜.fs.pathで定義する)
package com.example.batchapp.jobflow; import com.asakusafw.vocabulary.flow.Export; import com.asakusafw.vocabulary.flow.FlowDescription; import com.asakusafw.vocabulary.flow.Import; import com.asakusafw.vocabulary.flow.In; import com.asakusafw.vocabulary.flow.JobFlow; import com.asakusafw.vocabulary.flow.Out; import com.example.modelgen.dmdl.model.ExampleModel; @JobFlow(name = "ExampleJob") public class ExampleJob extends FlowDescription { private In<ExampleModel> in; private Out<ExampleModel> out; public ExampleJob( @Import(name = "in", description = ExampleModelFromLocalCsv.class) In<ExampleModel> in, @Export(name = "out", description = ExampleModelToHdfsCsv.class) Out<ExampleModel> out ) { this.in = in; this.out = out; } @Override protected void describe() { this.out.add(this.in); //入力データをそのまま出力するだけ } }
package com.example.batchapp.batch; import com.asakusafw.vocabulary.batch.Batch; import com.asakusafw.vocabulary.batch.BatchDescription; import com.example.batchapp.jobflow.ExampleJob; @Batch(name = "ExampleBatch") public class ExampleBatch extends BatchDescription { @Override protected void describe() { run(ExampleJob.class).soon(); } }
Importer用のWindGateのプロファイルを定義する。
WindGateサーバーに配置するファイルの置き場として、src/dist/gatewayというディレクトリーを作成し、その下にファイルを置いておく。
(WindGateサーバーに配置する為のAsakusaアーカイブを作る際にsrc/dist/gatewayの下のファイルを含めるようにする)
デフォルトのASAKUSA_HOME/windgate/profile/asakusa.propertiesをコピーして、必要な部分を記述する。
プロファイルのファイル名は何でもよいが、ImporterのgetProfileName()と合わせる。
(ファイル名がzzz.propertiesなら、getProfileName()は「return "zzz";
」とする)
## Core core.maxProcesses=4 ## Resources # Local File System resource.local=com.asakusafw.windgate.stream.file.FileResourceProvider resource.local.basePath=/tmp/windgate # JDBC #resource.jdbc=com.asakusafw.windgate.jdbc.JdbcResourceProvider #resource.jdbc.driver=org.postgresql.Driver #resource.jdbc.url=jdbc:postgresql://localhost:5432/asakusa #resource.jdbc.user=asakusa #resource.jdbc.password=asakusa #resource.jdbc.batchGetUnit=1000 #resource.jdbc.batchPutUnit=1000 #resource.jdbc.connect.retryCount=3 #resource.jdbc.connect.retryInterval=10 #resource.jdbc.statement.truncate=TRUNCATE TABLE {0} #resource.jdbc.properties.loginTimeout=10 # Hadoop File System #resource.hadoop=com.asakusafw.windgate.hadoopfs.HadoopFsProvider #resource.hadoop.compression=org.apache.hadoop.io.compress.DefaultCodec #resource.hadoop.basePath=hdfs://localhost/user/${USER} # Hadoop File System (for Remote Hadoop Cluster via SSH) resource.hadoop=com.asakusafw.windgate.hadoopfs.jsch.JschHadoopFsProvider resource.hadoop.user=hadoop resource.hadoop.host=hishidama-hadoop resource.hadoop.port=22 resource.hadoop.privateKey=${HOME}/.ssh/id_dsa resource.hadoop.passPhrase=hishidama-ssh-password resource.hadoop.compression=org.apache.hadoop.io.compress.DefaultCodec resource.hadoop.env.HADOOP_CMD=/home/hadoop/bin/hadoop resource.hadoop.env.ASAKUSA_HOME=/home/hadoop/asakusa ## Session session=com.asakusafw.windgate.file.session.FileSessionProvider session.directory=${ASAKUSA_HOME}/windgate/var/session/${WINDGATE_PROFILE} ## Process process.basic=com.asakusafw.windgate.core.process.BasicProcessProvider
resource.local.basePathでローカルファイルシステムのパス(ディレクトリー)を指定する。
(RDBを対象にする場合は、resource.jdbc系のプロパティーを記述する)
resource.hadoopにはJschHadoopFsProviderの方を有効にする。
(デフォルトのプロファイルのasakusa.propertiesではHadoopFsProviderが有効になっているので、こちらはコメントアウトする)
resource.hadoopのuser・host・port・privateKey・passPhraseは、SSHで接続する情報。
resource.hadoopのenv.HADOOP_CMDやenv.ASAKUSA_HOMEは、接続先(つまりHadoopクラスターのマスターノード)内での場所を指定する。
今回の例では、WindGateサーバー上からYAESSを起動し、別の場所にあるHadoopクラスターを使用する。
YAESSには別サーバー(Hadoopクラスター)上にあるAsakusaアプリケーションを起動できる機能があるが、
その為に、HadoopクラスターにSSH接続できるようにWindGateサーバー上のYAESSも設定する必要がある。
デフォルトのASAKUSA_HOME/yaess/conf/yaess.propertiesをコピーして、必要な部分を記述する。
core = com.asakusafw.yaess.basic.BasicCoreProfile core.version = 0.1 ## file lock lock = com.asakusafw.yaess.basic.BasicLockProvider lock.scope = world lock.directory = ${ASAKUSA_HOME}/yaess/var/lock ## logging monitor monitor = com.asakusafw.yaess.basic.BasicMonitorProvider monitor.stepUnit = 0.05 ## single threaded job scheduler scheduler = com.asakusafw.yaess.basic.BasicJobScheduler ## local direct execution #hadoop = com.asakusafw.yaess.basic.BasicHadoopScriptHandler #hadoop.resource = hadoop-master #hadoop.env.HADOOP_CMD = /usr/bin/hadoop #hadoop.env.ASAKUSA_HOME = ${ASAKUSA_HOME} command.* = com.asakusafw.yaess.basic.BasicCommandScriptHandler command.*.resource = asakusa #command.*.env.HADOOP_CMD = /usr/bin/hadoop command.*.env.ASAKUSA_HOME = ${ASAKUSA_HOME} ## multi-threaded job scheduler (requires asakusa-yaess-paralleljob plug-in) #scheduler = com.asakusafw.yaess.paralleljob.ParallelJobScheduler #scheduler.parallel.default = 3 #scheduler.parallel.hadoop-master = 1 ### remote execution via SSH (requires asakusa-yaess-jsch plug-in) hadoop = com.asakusafw.yaess.jsch.SshHadoopScriptHandler hadoop.ssh.user=hadoop hadoop.ssh.host=hishidama-hadoop hadoop.ssh.port=22 hadoop.ssh.privateKey=${HOME}/.ssh/id_dsa hadoop.ssh.passPhrase=hishidama-ssh-password hadoop.resource = hadoop-master hadoop.env.HADOOP_CMD = /home/hadoop/bin/hadoop hadoop.env.ASAKUSA_HOME = /home/hadoop/asakusa #command.* = com.asakusafw.yaess.jsch.SshCommandScriptHandler #command.*.ssh.user=asakusa #command.*.ssh.host=localhost #command.*.ssh.port=22 #command.*.ssh.privateKey=${HOME}/.ssh/id_dsa #command.*.ssh.passPhrase= #command.*.resource = asakusa #command.*.env.HADOOP_CMD = /usr/bin/hadoop #command.*.env.ASAKUSA_HOME = ${ASAKUSA_HOME}
設定内容はWindGateのプロファイルのresource.hadoopと同様。
Exporter用のDirect I/Oのプロパティーファイルを定義する。
これはHadoopクラスター側の設定となるので、src/dist/hadoopというディレクトリーを作成し、その下にファイルを置いておく。
(Hadoopクラスターに配置する為のAsakusaアーカイブを作る際にsrc/dist/hadoopの下のファイルを含めるようにする)
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>com.asakusafw.runtime.core.Report.Delegate</name> <value>com.asakusafw.runtime.report.CommonsLoggingReport</value> </property> <property> <name>com.asakusafw.directio.hadoop</name> <value>com.asakusafw.runtime.directio.hadoop.HadoopDataSource</value> </property> <property> <name>com.asakusafw.directio.hadoop.path</name> <value>hadoop</value> </property> <property> <name>com.asakusafw.directio.hadoop.fs.path</name> <value>/tmp/directio/example</value> </property> </configuration>
これは普通のDirect I/Oの定義と同じ。
今回の例ではhadoopという名前で定義している。
ここではfs.pathに「/tmp/directio/example」というローカルのディレクトリーを指定しているが、
実際のHadoopクラスターが対象であれば「hdfs://〜」というHDFSのパスになるだろう。
AsakusaアプリケーションをビルドしてAsakusaアーカイブを作り、実行するサーバーに配置(デプロイ)する。
$ cd Asakusaプロジェクト $ ./gradlew clean compileBatchapp
$ ./gradlew attachBatchapps attachConfGateway assembleAsakusafw
$ cd /home/asakusa $ mkdir asakusa $ cd asakusa $ tar xf ~/asakusafw-0.6.1.tar.gz
$ ./gradlew attachBatchapps attachConfHadoop assembleAsakusafw
$ cd /home/hadoop $ mkdir asakusa $ cd asakusa $ tar xf ~/asakusafw-0.6.1.tar.gz
gradlewコマンドの引数のattachConfGatewayやattachConfHadoopがポイント。
attachConfGatewayだとsrc/dist/gatewayの下のファイルがアーカイブに含まれ、
attachConfHadoopだとsrc/dist/hadoopの下のファイルがアーカイブに含まれる。
※compileBatchappとattachは別々に行う必要がある。WindGateサーバー用とHadoopクラスター用でAsakusaアプリケーションのビルドバージョンを一致させる必要がある為。
まずは入力データを用意する。
今回の例ではWindGateサーバー上に入力データとなるCSVファイルを用意する。
今回はWindGateプロファイルのresource.local.basePathが「/tmp/windgate」でImporterのgetPath()が「input/example.csv」なので、
WindGateサーバー上の「/tmp/windgate/input/example.csv」が入力ファイルとなる。
abc,def foo,bar
実行はWindGateサーバー(asakusaユーザー)上で行う。
$ export ASAKUSA_HOME=$HOME/asakusa $ cd $ASAKUSA_HOME $ yaess/bin/yaess-batch.sh ExampleBatch
これで、実行が成功すればHadoopクラスター側(HDFS上)にファイルが出力される。
$ hadoop fs -ls /tmp/directio/example/output Found 1 items -rwxrwxrwx 1 hadoop hadoop 18 2014-03-29 11:07 /tmp/directio/example/output/example0000.csv $ hadoop fs -cat /tmp/directio/example/output/example0000.csv abc,def foo,bar
core/conf/asakusa-resources.xmlのcom.asakusafw.directio.〜.fs.pathが「/tmp/directio/example」でExporterのgetResourcePattern()が「output/example*.csv」なので、
HDFS上(今回はスタンドアローンなので実際はローカルファイルシステム上だが)に「/tmp/directio/example/output/example0000.csv」が作られる。
なお、最初は環境設定まわりで色々エラーが出るだろうから、ドライランを指定して実行するのがよい。
$ yaess/bin/yaess-batch.sh ExampleBatch -D dryRun 2>&1 | tee /tmp/log.txt
実行しようとした際によく出るエラーについて。
which: no hadoop in (/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/asakusa/bin)
〜
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/cli/CommandLineParser
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2442)
at java.lang.Class.getMethod0(Class.java:2685)
at java.lang.Class.getMethod(Class.java:1620)
at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:492)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:484)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.cli.CommandLineParser
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
〜
YAESSはhadoopコマンドの場所を元にしてHadoopのライブラリーを取得する。
上記のエラーメッセージは、hadoopコマンドが見つからないのでHADOOP_HOMEが特定できず、
HADOOP_HOME/libの下にあるCommandLineParserのjarファイルを読み込めていない為に発生している。
hadoopコマンドの場所は環境変数HADOOP_CMDで指定する。
(環境変数HADOOP_HOMEを定義するのでも構わないのだが、HADOOP_HOMEは非推奨となっているのでなるべく使わない)
$ export HADOOP_CMD=/home/hadoop/bin/hadoop
$ ls $HADOOP_CMD …ちゃんと見えることを確認する
もしくは、hadoopコマンドにパスを通せばよい。
Error: JAVA_HOME is not set. WindGate failed with exit code: 1
YAESSでは環境変数JAVA_HOMEを参照するので、定義しておく必要がある。
$ export JAVA_HOME=/usr/java/default
2014/03/29 10:34:04 INFO [WG-HADOOP_FS-I30004] Remote command started: ASAKUSA_HOME="/home/hadoop/asakusa" _ASAKUSA_APP_EXECUTION_MODE="simulation" _ASAKUSA_APP_BATCH_ID="ExampleBatch" HADOOP_CMD="/home/hadoop/bin/hadoop" _ASAKUSA_APP_BUILD_ID="7670f5b8-85ce-4a17-8a86-468e3c78e5ec" "/home/hadoop/asakusa/windgate-ssh/libexec/put.sh" (resource=hadoop, target=hadoop@hishidama-hadoop:22) [ExampleBatch|ExampleJob]
com.asakusafw.windgate.hadoopfs.ssh.WindGateHadoopPut
Error: JAVA_HOME is not set.
com.asakusafw.windgate.hadoopfs.ssh.WindGateHadoopPut failed with exit code: 1
〜
2014/03/29 10:34:04 ERROR [WG-HADOOP_FS-E14001] Failed to exit command (resource=hadoop, process=in, path=[target/hadoopwork/012447d7-5648-4cba-83af-4bf3abd97340/ExampleBatch/ExampleJob/prologue/windgate/in]) [ExampleBatch|ExampleJob]
2014/03/29 10:34:04 ERROR [WG-CORE-E05003] Failed to close drain driver: in local->hadoop [ExampleBatch|ExampleJob]
java.io.IOException: SSH connection returns unexpected exit code: (code=1, process=in:drain)
at com.asakusafw.windgate.hadoopfs.ssh.AbstractSshHadoopFsMirror$SshDrainDriver.close(AbstractSshHadoopFsMirror.java:426) ~[na:na]
at com.asakusafw.windgate.core.process.BasicProcessProvider.execute(BasicProcessProvider.java:99) ~[asakusa-windgate-core-0.6.1.jar:na]
〜
WindGateで接続する先のサーバーにも環境変数JAVA_HOMEを定義しておく必要がある。
(リモート(今回の例ではHadoopクラスターのマスターノード)の/etc/bashrcとかに書いておけば読み込まれる)
これはWindGateのプロファイルに記述しておくことも出来る。
resource.hadoop.env.JAVA_HOME=/usr/java/default
2014/03/29 10:42:58 INFO [YS-JSCH-I00004] Opened SSH command channel: user=hadoop, host=hishidama-hadoop, port=22, id=/home/asakusa2/.ssh/id_dsa, executable=/home/hadoop/asakusa/yaess-hadoop/libexec/hadoop-execute.sh, elapsed=148ms
Starting Asakusa Hadoop:
Hadoop Command: /home/hadoop/bin/hadoop
App Library: /home/hadoop/asakusa/batchapps/ExampleBatch/lib/jobflow-ExampleJob.jar
Batch ID: ExampleBatch
Flow ID: ExampleJob
Execution ID: e4a77444-9478-4ce5-a376-b7d5f6028b84
Class: com.example.batchapp.exampleBatch.exampleJob.directio.epilogue.StageClient
Error: JAVA_HOME is not set.
YAESS Hadoop failed with exit code: 1
〜
2014/03/29 10:42:58 ERROR [YS-CORE-E04001] Job "epilogue.directio" execution was failed: batchId=ExampleBatch, flowId=ExampleJob, executionId=e4a77444-9478-4ce5-a376-b7d5f6028b84, phase=epilogue, jobId=epilogue.directio, serviceId=hadoop, trackingId=YAESS/ExampleBatch/ExampleJob/epilogue/e4a77444-9478-4ce5-a376-b7d5f6028b84/epilogue.directio
com.asakusafw.yaess.basic.ExitCodeException: Unexpected exit code from Hadoop job: code=1 (batch=ExampleBatch, flow=ExampleJob, phase=epilogue, stage=epilogue.directio, exection=e4a77444-9478-4ce5-a376-b7d5f6028b84)
at com.asakusafw.yaess.basic.ProcessHadoopScriptHandler.execute0(ProcessHadoopScriptHandler.java:278) ~[asakusa-yaess-core-0.6.1.jar:na]
at com.asakusafw.yaess.basic.ProcessHadoopScriptHandler.execute(ProcessHadoopScriptHandler.java:206) ~[asakusa-yaess-core-0.6.1.jar:na]
〜
YAESSで接続する先のサーバーにも環境変数JAVA_HOMEを定義しておく必要がある。
(リモート(今回の例ではHadoopクラスターのマスターノード)の/etc/bashrcとかに書いておけば読み込まれる)
これはYAESSのプロパティーファイルに記述しておくことも出来る。
hadoop.env.JAVA_HOME=/usr/java/default
com.asakusafw.runtime.core.context.InconsistentApplicationException: Inconsistent application, please check your deployed application: url="jar:file:/home/hadoop/asakusa/batchapps/ExampleBatch/lib/jobflow-ExampleJob.jar!/META-INF/asakusa/application.properties", batchId="ExampleBatch", caller="7670f5b8-85ce-4a17-8a86-468e3c78e5ec", callee="ed992636-1bc7-4d76-b937-7101d800d04f", hostname="192.168.1.24 38515 192.168.1.23 22"
at com.asakusafw.runtime.core.context.RuntimeContext.verifyBuildId(RuntimeContext.java:366)
at com.asakusafw.runtime.core.context.RuntimeContext.verifyApplication(RuntimeContext.java:317)
at com.asakusafw.runtime.stage.BaseStageClient.run(BaseStageClient.java:120)
at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:65)
〜
ローカル(今回の例ではWindGateサーバー)とリモート(今回
の例ではHadoopクラスターのマスターノード)にAsakusaアプリケーションを配置するが、
YAESSは実行前にそれらのバージョンが同じかどうかをチェックしており、ビルドバージョンが違っていたらエラーになる。
Asakusaアプリケーションをビルドしたら、双方のサーバーにAsakusaアプリケーションを配置しなおす必要がある。
2014/03/29 10:21:11 ERROR [WG-STREAM-E03001] Failed to open input stream: /tmp/windgate/input/example.csv (resource=local, process=in) [ExampleBatch|ExampleJob]
java.io.FileNotFoundException: /tmp/windgate/input/example.csv (そのようなファイルやディレクトリはありません)
at java.io.FileInputStream.open(Native Method) ~[na:1.7.0_45]
at java.io.FileInputStream.<init>(FileInputStream.java:146) ~[na:1.7.0_45]
at com.asakusafw.windgate.stream.file.FileInputStreamProvider.openStream(FileInputStreamProvider.java:78) ~[asakusa-windgate-stream-0.6.1.jar:na]
〜
単なる入力ファイルの作り忘れ^^;
WindGate(CSV)の場合はローカルファイルを扱うことになるので、ログに表示されているパスは素直にローカルファイルシステム上の場所となる。