夢とガラクタの集積場

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

StormのコマンドはClojureを使用しているので起動が遅い?

こんにちは。

では、引き続きStormのコマンドが遅い理由について確認してみます。

1.Topology起動と、他のコマンドの違いは何なのか?

前回は、単にJVMの起動が遅いのではないか、レベルでとどまってしまいましたが、それではわからない点が1つあります。
「Topology起動と、他のコマンドの違いは何なのか?」ということです。

Topology起動時のJVM起動は1秒ほどで動いているにも関わらず、
他のコマンド(list/activate/deactivate/rebalance/kill)は5秒ほどかかっていました。
この違いは一体何なのでしょうか。

というわけで、前回の結果より、各コマンドを起動した時のJavaコマンド(クラスパス除く)を取得してみました。
#クラスパスは見た感じほぼ同じでしたので、それは影響しないとまずは仮定します。

■Topology起動

java -client -Dstorm.options= -Dstorm.home=/opt/storm-0.9.4 (クラスパス) storm.starter.ExclamationTopology ExclamationTopology

■Topology一覧取得(list)

java -client -Dstorm.options= -Dstorm.home=/opt/storm-0.9.4 (クラスパス) backtype.storm.command.list

■Topology有効化(activate)

java -client -Dstorm.options= -Dstorm.home=/opt/storm-0.9.4 (クラスパス) backtype.storm.command.activate ExclamationTopology

■Topology無効化(deactivate)

java -client -Dstorm.options= -Dstorm.home=/opt/storm-0.9.4 (クラスパス) backtype.storm.command.deactivate ExclamationTopology

■Topology再配置(rebalance)

java -client -Dstorm.options= -Dstorm.home=/opt/storm-0.9.4 (クラスパス) backtype.storm.command.rebalance ExclamationTopology

■Topology終了(kill)

java -client -Dstorm.options= -Dstorm.home=/opt/storm-0.9.4 (クラスパス) backtype.storm.command.kill_topology ExclamationTopology

■設定値取得(追加)

java -client -Dstorm.options= -Dstorm.conf.file= (クラスパス) backtype.storm.command.config_value storm.log.dir

Topology起動とそれ以外のコマンドの違いは何でしょうか。
それは、Javaのクラスを起動しているか、Clojureのクラスを起動しているか」の違いです。
とはいえ、Clojureのクラスといっても実際にJVMで起動する際にJavaのクラスと違いが発生するものとは思えません。
では、何が違うんでしょう。

2.Javaクラス起動時とClojureクラス起動時の違い

とりあえず、違いがわかっているわけではないため、適当な仮定をつけながらあたりをつけていきます。
まず一つ目は、Clojureのクラスはコンパイル時に依存するクラスが大量に追加されているのではないか?」ということですね。
当然、JVM上で違う言語を動作させるわけですからコンパイル時等にそのあたりをラッピングさせる機構が働いているはずです。
ですので、そのラッピングするためのクラスが重いのではないか、という予測です。

というわけで、実際に起動時のロードクラスを見て確認してみましょう。
■Topology起動
Javaで書かれたTopology起動の結果は下記のようになり、ロードされたクラス数は1594クラスでした。
思ったより依存するクラスは多いわけですね。

java -client -verbose:class -Dstorm.options= -Dstorm.home=/opt/storm-0.9.4 (クラスパス) storm.starter.ExclamationTopology ExclamationTopology
[Loaded java.lang.Object from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]
[Loaded java.io.Serializable from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]
[Loaded java.lang.Comparable from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]
[Loaded java.lang.CharSequence from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]
[Loaded java.lang.String from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]
(省略)
[Loaded backtype.storm.generated.Nimbus$submitTopology_args from file:/opt/storm-0.9.4/lib/storm-core-0.9.4.jar]
[Loaded backtype.storm.generated.Nimbus$submitTopology_args$_Fields from file:/opt/storm-0.9.4/lib/storm-core-0.9.4.jar]
[Loaded org.apache.thrift7.protocol.TMap from file:/opt/storm-0.9.4/lib/storm-core-0.9.4.jar]
[Loaded backtype.storm.generated.ComponentObject$1 from file:/opt/storm-0.9.4/lib/storm-core-0.9.4.jar]
[Loaded backtype.storm.generated.Grouping$1 from file:/opt/storm-0.9.4/lib/storm-core-0.9.4.jar]
[Loaded backtype.storm.generated.Nimbus$submitTopology_result from file:/opt/storm-0.9.4/lib/storm-core-0.9.4.jar]
[Loaded backtype.storm.generated.Nimbus$submitTopology_result$_Fields from file:/opt/storm-0.9.4/lib/storm-core-0.9.4.jar]
619  [main] INFO  backtype.storm.StormSubmitter - Finished submitting topology: ExclamationTopology
[Loaded java.lang.Shutdown from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]
[Loaded java.lang.Shutdown$Lock from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]

■Topology一覧取得(list)
で、次はClojureで書かれたTopology一覧取得コマンドの実行時です。
実行してみると・・・?

java -client -verbose:class -Dstorm.options= -Dstorm.home=/opt/storm-0.9.4 (クラスパス) backtype.storm.command.list
[Loaded java.lang.Object from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]
[Loaded java.io.Serializable from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]
[Loaded java.lang.Comparable from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]
[Loaded java.lang.CharSequence from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]
[Loaded java.lang.String from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]
(省略)
[Loaded clojure.lang.IDeref from file:/opt/storm-0.9.4/lib/clojure-1.5.1.jar]
[Loaded clojure.lang.IRef from file:/opt/storm-0.9.4/lib/clojure-1.5.1.jar]
[Loaded clojure.lang.Settable from file:/opt/storm-0.9.4/lib/clojure-1.5.1.jar]
[Loaded clojure.lang.IMeta from file:/opt/storm-0.9.4/lib/clojure-1.5.1.jar]
[Loaded clojure.lang.IReference from file:/opt/storm-0.9.4/lib/clojure-1.5.1.jar]
(省略)
No topologies running.
[Loaded java.lang.Shutdown from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]
[Loaded java.lang.Shutdown$Lock from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.65.x86_64/jre/lib/rt.jar]

・・・あれ?なんかやたらと多いですね。
省略した分も含めると4720クラスのロードが行われていました。
特に、clojure、という名のつくクラスが多く、2700をオーバーする数のロードが行われていました。

他のコマンドも実行してみた結果は下記になります。

No コマンド 機能 ロードクラス数
1 jar TopologyをStormクラスタにデプロイ 1594 クラス
2 list StormクラスタのTopology一覧取得 4720 クラス
3 activate Topologyを有効化 4714 クラス
4 deactivate Topologyを無効化 4714 クラス
5 rebalance Topologyを再配置 4755 クラス
6 kill Topologyを終了 4752 クラス
7 configvalue 設定値読込 4544 クラス

3.わかったことは?

この結果からわかることは、下記あたりでしょうか。

  • JVM起動時にClojureのプログラムはJavaプログラムと比して3倍以上のクラスをロードする。
    • 結果、Clojureを実行するプログラムは起動に時間がかかる。

ともあれ、今回の結論としては、
StormのコマンドはClojureのクラスをロードして使用しているため、遅い
ということになりますね。

逆に言えば、StormのコマンドをClojureを使用せずにJavaで置き換えることができたなら、
それだけで大幅な高速化が出来るのはないでしょうか。

ただ、それは次回にでも。