「zkServer.sh でサーバー起動しているはずなんだけど・・・」と思いながら、zookeeper.out というファイルの中身を見たら、「line 109: nohup: command not found」というエラーメッセージを発見。Windows の Git Bash で作業していたから、「nohup アップというコマンドがない」というエラーが起こってたということか。起動に失敗したのなら、エラー表示くらいしてくれよ > zkServer.sh
Windows では zkServer.sh ではなくて zkServer.cmd を使うべき、ということで、「zkServer.cmd conf\zoo.cfg」という形で起動したら、またもやエラー。
2015-06-16 19:43:30,086 [myid:] - WARN [main:QuorumPeerMain@113] - Either no config or no quorum defined in config, run ning in standalone mode 2015-06-16 19:43:30,158 [myid:] - ERROR [main:ZooKeeperServerMain@54] - Invalid arguments, exiting abnormally java.lang.NumberFormatException: For input string: "(略)\zookeeper-3.4.6\bin\..\conf\zoo.cfg" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:580) at java.lang.Integer.parseInt(Integer.java:615) at org.apache.zookeeper.server.ServerConfig.parse(ServerConfig.java:60) at org.apache.zookeeper.server.ZooKeeperServerMain.initializeAndRun(ZooKeeperServerMain.java:83) at org.apache.zookeeper.server.ZooKeeperServerMain.main(ZooKeeperServerMain.java:52) at org.apache.zookeeper.server.quorum.QuorumPeerMain.initializeAndRun(QuorumPeerMain.java:116) at org.apache.zookeeper.server.quorum.QuorumPeerMain.main(QuorumPeerMain.java:78) 2015-06-16 19:43:30,163 [myid:] - INFO [main:ZooKeeperServerMain@55] - Usage: ZooKeeperServerMain configfile | port datadir [ticktime] [maxcnxns] Usage: ZooKeeperServerMain configfile | port datadir [ticktime] [maxcnxns]
このエラーメッセージがまた意味が分かりにくいため、結局 QuorumPeerMain.java, ZooKeeperServerMain.java, ServerConfig.java やらのソースコードを読むことになって、「汚いコードだな」とげんなり。
parseInt でエラーが発生している箇所 (ServerConfig.java 60 行目) は、コマンドライン引数が 1 つだけのときには通らない場所なんだけどなぁ、、、あっ、zkServer.cmd で引数追加してるんだな、これは。(くそっ、先に zkServer.cmd みておくべきだった)
zkServer.cmd の中身はこんな感じ (途中に改行追加):
setlocal call "%~dp0zkEnv.cmd" set ZOOMAIN=org.apache.zookeeper.server.quorum.QuorumPeerMain echo on java "-Dzookeeper.log.dir=%ZOO_LOG_DIR%" "-Dzookeeper.root.logger=%ZOO_LOG4J_PROP%" ^ -cp "%CLASSPATH%" %ZOOMAIN% "%ZOOCFG%" %* endlocal
%ZOOMAIN% のあとに、%ZOOCFG% が挿入されてるぞ・・・。
しかし、こういう書き方をされると、設定ファイル名をコマンドライン引数として簡単に渡せなくなる。別の設定ファイルを使おうとすると、ZOOCFG 変数をいじってから zkServer.cmd を起動しないといけない。
「引数の数の違いによって、同じ位置にある引数なのに解釈の仕方を変えてしまう」、というのは、下手な設計。ZooKeeper サーバーのコマンドライン引数処理はひどい。ついでにいうと、設定ファイルのパース処理 (QuorumPeerConfig.parseProperties) もひどすぎる。
昔読んだ HBase のソースコードの汚さに比べたら全然マシだけど、なんか Hadoop まわりは力技感が半端ない。コード品質の悪さを人数でカバーか・・・。
結局、引数無しで zkServer.cmd を実行。手元の実験ならこれでいい。ダウンロードしてきた zookeeper のソースツリー (zookeeper-3.4.6) 外で作業しようとしたばっかりに、無駄な苦労をしてしまった。