この記事はAsakusa Framework Advent Calendar 2015の9日目です。
入門から先の記事はひしだまさんが大量に書いているので、ここでは箸やすめ的な入門記事を書いてみようと思います。
Asakusa on Sparkとは
Hadoop環境で実績のあるAsakusaFrameworkをSpark上でも動かせるようにしたものです。現在ベータ版でプロダクションで使うのをおすすめしませんと書いてありつつ、実際の稼働事例が出ていたりしますね。
説明を読むとAsakusaFrameworkはHadoopでもSparkでもどちらでも同じDSLで良いとあります。AsakusaやSparkを触ったことはないのですが、いきなり新しいSparkで開発を始めることにします。
以降の作業の前提として、Hadoop/Sparkの知識はなくとも構いません。Javaが動作して、環境変数JAVA_HOMEが設定してあることが条件です。
私の実行環境は、OSX(Capitan)、Java 1.8.0_65でした。
まず最初の落とし穴
AsakusaFrameworkの開発環境としては、Jinrikishaがあります。スターターパッケージと書いてあり、その名の通りこれをインストールすればHadoopもAsakusaもEclipseも入るというすぐれものです。
が
現時点においてJinrikishaはAsakusa on Sparkに対応していません。いろいろやればできる(できた)のですが、私自身はIntelliJユーザーということもあり、無理にここからスタートする必要もないので、今回はJinrikishaを使いません。
Hadoopのインストール
まずはHadoopをインストールしましょう。Sparkにhadoop同梱のパッケージもあるのですが、AsakusaFrameworkのジョブコントローラーであるYAESSはhadoopコマンドを使います。これはHadoopディストリビューションに含まれているので、(SparkではなくHadoopを)ちゃんと入れることにします。
インストールは、hadoopサイトからバイナリアーカイブをダウンロードして、適当なディレクトリに展開します。
展開が終わったら、インストールのテストをしてみます。
Hadoopをインストールしたディレクトリに移動し、
(https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html) のスクリプトを実行します。
$ mkdir input
$ cp etc/hadoop/*.xml input
$ bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.1.jar grep input output 'dfs[a-z.]+'
$ cat output/*
1 dfsadmin
と表示されると思います。
好みですが、私はバージョン付きのディレクトリに対してシンボリックリンクを貼ります。
$ ln -s hadoop-2.7.1 hadoop
Sparkのインストール
次にSparkをインストールします。Hadoop同様にダウンロードサイトからダウンロードしますが、幾つか選択肢がありますが、下記を選択します。
- Spark Release: 1.5.2 を選択
- Package Type: Pre-Built for Hadoop 2.6 and later を選択
Hadoopを既にインストールしているので、 Pre-build with user-provided Hadoop でもいいような気がしますが、かなりハマったのでここではHadoop同梱版を使います。
ダウンロードしたアーカイブを先ほどHadoopを展開したあたりに展開します。展開後、動作確認をしましょう。
$ ./bin/spark-shell
http://spark.apache.org/docs/latest/quick-start.html にあるスクリプトを幾つか実施してみます。
正しく動作したら、hadoop同様シンボリックリンクを貼ります。
$ ln -s spark-1.5.2-bin-hadoop2.6 spark
Asakusa Gradle Pluginのインストール
Asakusa Gradle Pluginは、AsakusaFrameworkを使ったアプリケーションのビルドをgradleから行えるようにしたものです。
ちょうどサンプルプロジェクトもあるので、ダウンロードしてhadoop / sparkと同じように展開します。
build.gradleの修正
このサンプルプロジェクトはAsakusa on Hadoop1の前提で作られているので、Asakusa on Spark用に修正します。修正箇所は
- 7行目: asakusa-spark-gradleプラグインを依存関係に追加
- 19行目: asakusafw-sparkプラグインの有効化
- 22行目: asakusafwVersionの修正
- 43行目: hadoop-clientのバージョンの修正
です。
なお、apply plugin: 'idea'
を追記することで、IntelliJ用のプロジェクトファイルを生成できます。
buildscript {
repositories {
maven { url 'http://asakusafw.s3.amazonaws.com/maven/releases' }
}
dependencies {
//classpath group: 'com.asakusafw', name: 'asakusa-gradle-plugins', version: '0.7.6'
classpath group: 'com.asakusafw.spark', name: 'asakusa-spark-gradle', version: '0.2.1'
}
}
task wrapper(type: Wrapper) {
distributionUrl 'http://services.gradle.org/distributions/gradle-2.8-bin.zip'
jarFile file('.buildtools/gradlew.jar')
}
apply plugin: 'asakusafw'
apply plugin: 'asakusafw-organizer'
apply plugin: 'eclipse'
apply plugin: 'asakusafw-spark'
asakusafw {
asakusafwVersion '0.7.6-hadoop2'
modelgen {
modelgenSourcePackage 'com.example.modelgen'
}
compiler {
compiledSourcePackage 'com.example.batchapp'
}
}
asakusafwOrganizer {
profiles.prod {
asakusafwVersion asakusafw.asakusafwVersion
}
}
dependencies {
compile group: 'com.asakusafw.sdk', name: 'asakusa-sdk-core', version: asakusafw.asakusafwVersion
compile group: 'com.asakusafw.sdk', name: 'asakusa-sdk-directio', version: asakusafw.asakusafwVersion
compile group: 'com.asakusafw.sdk', name: 'asakusa-sdk-windgate', version: asakusafw.asakusafwVersion
provided (group: 'org.apache.hadoop', name: 'hadoop-client', version: '2.7.1') {
exclude module: 'junit'
exclude module: 'mockito-all'
exclude module: 'slf4j-log4j12'
}
}
環境変数の設定
AsakusaFrameworkを動かすのに必要な環境変数を設定します。.asakusa_profile
ファイルに定義して、source
するか、起動時に読み込むと良いでしょう。
export ASAKUSA_DEVELOP_HOME=[your woking directory]
export ASAKUSA_HOME=${ASAKUSA_DEVELOP_HOME}/asakusafw
export HADOOP_CMD=${ASAKUSA_DEVELOP_HOME}/hadoop/bin/hadoop
export HADOOP_CLIENT_OPTS=-Xmx512m
export PATH=$JAVA_HOME/bin:$PATH:${ASAKUSA_DEVELOP_HOME}/hadoop/bin:${HIVE_HOME}/bin:$ASAKUSA_HOME/yaess/bin:$PATH
export HADOOP_OPTS="-Dorg.xerial.snappy.tempdir=/tmp -Dorg.xerial.snappy.lib.name=libsnappyjava.jnilib $HADOOP_OPTS"
上記で設定した、ASAKUSA_HOME
にasakusaFrameworkがインストールされます。
AsakusaFrameworkのインストール
gradleを使ってAsakusaFrameworkのインストールを行います。
$ ./gradlew installAsakusaFw
gradleとAsakusaFrameworkがインストールされます。
AsakusaFramework 設定
AsakusaFrameworkにSparkのspark-submit
コマンドの場所を設定します。
$ cd $ASAKUSA_HOME
$ echo "export SPARK_CMD=[Sparkをインストールしたディレクトリ]/bin/spark-submit"
ビルドとデプロイ
さて、サンプルアプリケーションをビルドします。
$ cd [サンプルプロジェクトホーム]
$ ./gradlew assemble
ビルドが終わると、build/spark-batchapps
ディレクトリに spark.example.summarizeSales
ディレクトリができているはずです。
確認できたら、デプロイを行います。
$ cp -r build/spark-batchapps/spark.example.summarizeSales $ASAKUSA_HOME/batchapps/
以上でAsakusaのSpark用バッチを実行する準備ができました。
サンプルデータの配置と実行
実行自体の手順は、Asakusa on Hadoopと変わりません。詳細な説明は(http://docs.asakusafw.com/latest/release/ja/html/introduction/start-guide.html#startguide-running-example) に記載されています。ここではコマンドのみ転載します。
サンプルデータの配置
# スタンドアロンモードに対応するため、ホームディレクトリに移動しておく
$ cd ~
# ファイルシステムパス上のデータをクリアしておく
$ hadoop fs -rmr target/testing/directio
# サンプルデータを配置する
$ hadoop fs -put [サンプルプロジェクトホーム]/src/test/example-dataset/master target/testing/directio/master
$ hadoop fs -put [サンプルプロジェクトホーム]/src/test/example-dataset/sales target/testing/directio/sales
YAESSの実行
$ASAKUSA_HOME/yaess/bin/yaess-batch.sh example.summarizeSales -A date=2011-04-01
わーっとログがでますが、最後に SUCCESSと表示されたら無事実行完了です。
結果の確認
$ hadoop fs -text file:~/target/testing/directio/result/category/result.csv
これでAsakusa on Sparkの開発環境ができました。Asakusaの開発をエンジョイしましょう。
おわりに
Asakusa on Sparkはベータということもあり、Getting Startedのようなドキュメントがなかったのでやってみましたが、思いの他苦労しました。このエントリではすんなり行く手順のみ書いてありますが、未解決の課題もあります。
-
IntelliJのGradleプラグインに環境変数を設定する方法がわからず、IntelliJからAsakusaビルドが動かない。(aoetkさんありがとうございます) - Hadoop同梱版のSparkを使わないと、snappyのネイティブライブラリが見つからないエラーが出る
- 環境変数 HADOOP_OPTSを設定しないと、snappyのネイティブライブラリが見つからないエラーが出る
単に解決方法が見つからなかっただけですので、解決したらエントリを修正することにしたいと思います。
なおここまで書いておいてなんですが、AsakusaDSLは再コンパイルだけでSparkで動きますので、AsakusaFrameworkに慣れるだけであれば、Jinrikishaが楽でいいと思います(^^;;