夢とガラクタの集積場

落ちこぼれ三流エンジニアである管理人の夢想=『夢』と、潰えた夢=『ガラクタ』の集積場です。

Apache Kafkaの最新版をビルドしてみる

こんにちは。

Clojureでの環境問題も解決したので一度Kafkaの方も進めておきます。
概要がわかったので、実際に動かしてみようとKafkaのサイトに向かったところ・・・

最新版の0.8.0系のアーカイブが存在しないという状態でした。

0.8.0のページ。ダウンロードページからダウンロードしてね、というリンク。

ダウンロードページには0.7.2までしかアーカイブが置いていない・・・・

ですが、「Getting the code」のページに従い、下記のコマンドを実行してみると、
バージョンは「0.8-SNAPSHOT」のソースをダウンロードすることができました。

git clone http://git-wip-us.apache.org/repos/asf/kafka.git kafka

そのため、「0.8-SNAPSHOT」のソースをビルドしてアーカイブを作成してみようと思います。
尚、このあたりはhttps://github.com/apache/kafkaからダウンロードしてもOKでした。

1.まずはsbtを実行してみる

https://github.com/apache/kafka を見てみるとビルドコマンドも載っているため、実行してみます。

C:\Develop\Source\GitHub\kafka [trunk]> .\sbt.bat "++2.9.2 package"
Getting org.scala-sbt sbt 0.12.1 ...
(依存性解決等)
[info] Packaging C:\Develop\Source\GitHub\kafka\contrib\hadoop-consumer\target\h
adoop-consumer-0.8-SNAPSHOT.jar ...
[info] Done packaging.
[success] Total time: 157 s, completed 2013/05/26 19:41:41

おお。とりあえず通ってしまった。
あっけなく通ってしまったのでディレクトリを確認してみますが、とりあえずjarファイルは生成されているものの、
パッケージ化はされていないようです。
そのため、今度はパッケージ化用のコマンドを改めて実行してみます。

C:\Develop\Source\GitHub\kafka [trunk]> .\sbt.bat "++2.9.2 release-zip"
[info] Loading project definition from C:\Develop\Source\GitHub\kafka\project
[info] Set current project to Kafka (in build file:/C:/Develop/Source/GitHub/kafka/)
Setting version to 2.9.2
[info] Set current project to Kafka (in build file:/C:/Develop/Source/GitHub/kafka/)
[error] Not a valid command: release-zip
[error] Expected '/'
[error] Expected ':'
[error] Not a valid key: release-zip
[error] release-zip
[error]            ^

残念ながら実行失敗。
なので、とりあえず色々コマンドを実行してみます。

C:\Develop\Source\GitHub\kafka [trunk]> .\sbt.bat "++2.9.2 tasks"
[info] Loading project definition from C:\Develop\Source\GitHub\kafka\project
[info] Set current project to Kafka (in build file:/C:/Develop/Source/GitHub/kafka/)
Setting version to 2.9.2
[info] Set current project to Kafka (in build file:/C:/Develop/Source/GitHub/kafka/)

This is a list of tasks defined for the current project.
It does not list the scopes the tasks are defined in; use the 'inspect' command for that.
Tasks produce values.  Use the 'show' command to run the task and print the resulting value.

  clean             Deletes files produced by the build, such as generated sources, compiled classes, and task caches.
  compile           Compiles sources.
  console           Starts the Scala interpreter with the project classes on the classpath.
  console-project   Starts the Scala interpreter with the sbt and the build definition on the classpath and useful imports.
  console-quick     Starts the Scala interpreter with the project dependencies on the classpath.
  copy-resources    Copies resources to the output directory.
  doc               Generates API documentation.
  package           Produces the main artifact, such as a binary jar.  This is typically an alias for the task that actually does the packaging.
  package-bin       Produces a main artifact, such as a binary jar.
  package-doc       Produces a documentation artifact, such as a jar containing API documentation.
  package-src       Produces a source artifact, such as a jar containing sources and resources.
  publish           Publishes artifacts to a repository.
  publish-local     Publishes artifacts to the local repository.
  run               Runs a main class, passing along arguments provided on the command line.
  run-main          Runs the main class selected by the first argument, passing the remaining arguments to the main method.
  test              Executes all tests.
  test-only         Executes the tests provided as arguments or all tests if no arguments are provided.
  test-quick        Executes the tests that either failed before, were not run or whose transitive dependencies changed, among those provided as arguments.
  update            Resolves and optionally retrieves dependencies, producing areport.

More tasks may be viewed by increasing verbosity.  See 'help tasks'.

どうやら、そもそもGitHubに書かれているrelease-zipなんてコマンド自体がないようです。
なので、アーカイブ化はあきらめて、生成されたJarファイルとシェルファイルでサーバ上で起動させてみよう・・・
と思いきや、シェルのクラスパス解決が下記のようになっておりivy2のローカルリポジトリにファイルがあるという
前提になっているようです。
しかもScalaのバージョンは2.8.0限定。
・・・とまぁ、Scalaバージョンについては変数化してさしかえればいいだけなのですが、
ivyについては厄介ですね。

  • kafka-run-class.sh
base_dir=$(dirname $0)/..

USER_HOME=$(eval echo ~${USER})
ivyPath=$(echo "$USER_HOME/.ivy2/cache")

snappy=$(echo "$ivyPath/org.xerial.snappy/snappy-java/bundles/snappy-java-1.0.4.1.jar")
CLASSPATH=$CLASSPATH:$snappy

library=$(echo "$ivyPath/org.scala-lang/scala-library/jars/scala-library-2.8.0.jar")
CLASSPATH=$CLASSPATH:$library

そんなわけで、
「あるディレクトリ配下にアーカイブを展開して、依存するファイルは全てその配下に置く」という
方式を取るためにはそれなりに手間がかかりそうです。

ちなみに、下記のページみたいにKafkaを動かした事例ページもあるんですが、
この場合はKafkaのGitHubをフォークして起動スクリプトやらを修正したものを使用しているようです。
http://www.michael-noll.com/blog/2013/03/13/running-a-multi-broker-apache-kafka-cluster-on-a-single-node/

このあたりを使った方がいいのかもしれませんね。
ともあれ、それなりに気長な話になるかもしれませんが、やってみます。

2013/05/27追記
id:xuweiさんからコメント頂き、sbt-packプラグインを用いることで
依存ライブラリを一か所にまとめる方法を教えていただきました。

そのため、試してみました。

やったことは下記の2点です。

1.sbt-packプラグインの定義をplugins.sbtに追記

project/plugins.sbtに下記のようにプラグイン定義を追記しました。

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.8.5")

addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.2.0")

addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.2") // ★追記★
2.Build.scalaにsbt-packプラグインを用いたProject定義を追記

下記2か所にpackプラグインについて追記しました。

import sbt._
import Keys._
import xerial.sbt.Pack._ // ★追記★
import java.io.File
// ★各行に「++ packSettings」を追記★
  lazy val kafka    = Project(id = "Kafka", base = file(".")).aggregate(core, examples, contrib, perf).settings((commonSettings ++ packSettings ++ runRatTask): _*)
  lazy val core     = Project(id = "core", base = file("core")).settings(commonSettings: _*).settings(coreSettings ++ packSettings: _*)
  lazy val examples = Project(id = "java-examples", base = file("examples")).settings(commonSettings ++ packSettings:_*) dependsOn (core)
  lazy val perf     = Project(id = "perf", base = file("perf")).settings((Seq(name := "kafka-perf") ++ commonSettings ++ packSettings):_*) dependsOn (core)

  lazy val contrib        = Project(id = "contrib", base = file("contrib")).aggregate(hadoopProducer, hadoopConsumer).settings(commonSettings ++ packSettings:_*)
  lazy val hadoopProducer = Project(id = "hadoop-producer", base = file("contrib/hadoop-producer")).settings(hadoopSettings ++ commonSettings ++ packSettings: _*) dependsOn (core)
  lazy val hadoopConsumer = Project(id = "hadoop-consumer", base = file("contrib/hadoop-consumer")).settings(hadoopSettings ++ commonSettings ++ packSettings: _*) dependsOn (core)

その上で、下記のようにpack-archiveコマンドを実行しました。
すると、「Kafka-0.8-SNAPSHOT.tar.gz」が生成され、
libディレクトリ配下にビルド成果物のjarファイルと、依存するjarファイルがまとめられていました。

sbt "++2.9.2 pack"
sbt "++2.9.2 pack-archive"
〜〜〜
[info] Generating target\Kafka-0.8-SNAPSHOT.tar.gz
[success] Total time: 16 s, completed 2013/05/27 5:10:02

ちなみにlibディレクトリ配下にまとめられたファイル一覧は下記。
・・・60個て、手動で出来るレベルでは無いですね(汗

antやavroでバージョン異なるライブラリが混じっているため、
単にlib配下を一律でクラスパス・・というわけにはいかないようですが、
それは除外定義で何とかなるでしょう。

なので、残るは除外定義の追加と起動スクリプトの改修ですかね。

oro-2.0.8.jar
paranamer-2.2.jar
paranamer-ant-2.2.jar
paranamer-generator-2.2.jar
pig-0.8.0.jar
piggybank.jar
qdox-1.10.1.jar
sbt-launch.jar
scala-compiler-2.9.2.jar
scala-library-2.9.2.jar
servlet-api-2.5-6.1.14.jar
servlet-api-2.5-20081211.jar
slf4j-api-1.6.4.jar
slf4j-simple-1.6.4.jar
snappy-java-1.0.4.1.jar
velocity-1.6.4.jar
xmlenc-0.52.jar
zkclient-0.1.jar
zkclient-20120522.jar
zookeeper-3.3.4.jar
ant-1.6.5.jar
ant-1.7.1.jar
ant-launcher-1.7.1.jar
apache-rat-0.8.jar
asm-3.2.jar
avro-1.3.2.jar
avro-1.4.0.jar
commons-cli-1.2.jar
commons-codec-1.4.jar
commons-collections-3.2.1.jar
commons-el-1.0.jar
commons-httpclient-3.1.jar
commons-lang-2.5.jar
commons-logging-1.1.1.jar
commons-net-1.4.1.jar
contrib_2.9.2-0.8-SNAPSHOT.jar
core-3.1.1.jar
hadoop-consumer-0.8-SNAPSHOT.jar
hadoop-core-0.20.2.jar
hadoop-producer-0.8-SNAPSHOT.jar
hsqldb-1.8.0.10.jar
jackson-core-asl-1.5.5.jar
jackson-mapper-asl-1.5.5.jar
jasper-compiler-5.5.12.jar
jasper-runtime-5.5.12.jar
jets3t-0.7.1.jar
jetty-6.1.22.jar
jetty-util-6.1.22.jar
jopt-simple-3.2.jar
jsp-2.1-6.1.14.jar
jsp-api-2.1-6.1.14.jar
junit-4.8.1.jar
kafka_2.9.2-0.8-SNAPSHOT.jar
kafka-java-examples-0.8-SNAPSHOT.jar
kafka-perf_2.9.2-0.8-SNAPSHOT.jar
kfs-0.3.jar
log4j-1.2.15.jar
metrics-annotation-3.0.0-c0c8be71.jar
metrics-core-3.0.0-c0c8be71.jar
netty-3.2.1.Final.jar