どぅーちゅいむーにー

これ、Twitterでよくね?という日々の記録かも

クラスタの構築

前回のエントリの最後に「Programmers Guideをみると、クライアントプログラムなどの作成方法などが解説されていますが、とりあえず今回は HBase のほうに進むということで、ZooKeeper についての話はいったんここで終わります。」なんて書きましたが、HBase のクラスタ環境を構築するためにはどうも ZooKeeper もクラスタ環境になっている必要があるようなので、ZooKeeper をクラスタ化してみます。
設定については、前回(d:id:k155e1:20100420:1271757128)を参照してください。


マニュアルでいうと Running Replicated ZooKeeper あたりからでしょうか。


HBase のところで出てきますが、HBase をクラスタで動作させる場合、ZooKeeper Quorum を事前に起動させておく必要があります(HDFS もですが)。
で、Quorum って何?という感じだったのですが、ZooKeeper のマニュアルにこういう一文がありました。

A replicated group of servers in the same application is called a quorum.

ちなみに、辞典をひくと「定」とか「数」とかいうらしい(ほんとか?)。余計にわけがわからなくなってきた。
まぁ、それはいいとして、とりあえず同一アプリケーション内のサーバグループ、ということでしょうか。

同一 quorum に所属するサーバは同一の設定を持つ、という定義になるようです。
というより、同一の設定をもつ ZooKeeper のサーバが1つのグループであり、それを quorum と呼ぶ、というほうが正しい?
サンプルとなる記述は以下。

tickTime=2000
dataDir=/var/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

ドキュメントではここで initLimit と syncLimit の説明をしています。
単位は tickTime になるようで、上記設定の場合、tickTime の単位はミリ秒のため、1 tickTime は 2秒、ということは、initLimit は 5 × 2秒の 10秒、syncLimit は 2 × 2秒の 4秒という感じだそうです。
server.Xは ZooKeeper が起動しているサーバを記述する感じで。
サーバ名(と思われる)のうしろの 2888 と 3888 はポート番号で、前のポート(2888)は他のサーバと接続するために使われるらしい。後者のほうは(quorumにおける?)リーダーを決めるための通信に使われるっぽいが、よくわかりません。
というわけで、今回の実験環境だとこんな感じでしょうか。

tickTime=2000
dataDir=/var/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=myhdfs1:2888:3888
server.2=myhdfs2:2888:3888
server.3=myhdfs3:2888:3888


  • myidファイルの準備

前述のように zoo.cfg ファイルを修正して myhdfs1 にて ZooKeeper サーバを起動しようとしたところ、エラーが発生して怒られたのですが、どうも、conf/zoo.cfg の dataDir で指定した場所(/home/issei/tmp/zookeeper/)に、myidというファイルを用意する必要があるようです。
このmyidファイルには、server.XX にあたる数値を記述しておく必要があるみたいです。

myhdfs1> cat /home/issei/tmp/zookeeper/myid
1

今回、myhdfs2 は 2、myhdfs3 は 3 が記述された myid ファイルを用意しました。

myhdfs2> pwd
/home/issei/tmp/zookeeper
myhdfs2> cat myid
2
myhdfs2> pwd
/home/issei/tmp/zookeeper
myhdfs3> cat myid
3


  • 動作確認1(事前確認)

前回は myhdfs1 のみで ZooKeeper を起動したので、myhdfs1 の設定を、myhdfs2、myhdfs3 に反映して起動してみます。
一応、起動前の各サーバの jps の結果。

myhdfs1> jps
17497 NameNode
17753 SecondaryNameNode
17946 TaskTracker
17825 JobTracker
20445 Jps
17613 DataNode
myhdfs2> jps
32536 Jps
30593 DataNode
30698 TaskTracker
myhdfs3> jps
13488 Jps
11815 DataNode
11914 TaskTracker



  • 動作確認2(失敗編)

myhdfs1 で ZooKeeper サーバを起動するのですが、zkServer.sh start 時、myid ファイルが存在しないとエラーになります。

myhdfs1> ./bin/zkServer.sh start
JMX enabled by default
Using config: /home/issei/app/zookeeper-3.3.0/bin/../conf/zoo.cfg
Starting zookeeper ...
STARTED
[issei@myhdfs1 zookeeper]$ 2010-04-21 13:54:45,476 - INFO  [main:QuorumPeerConfig@90] - Reading configuration from: /home/issei/app/zookeeper-3.3.0/bin/../conf/zoo.cfg
2010-04-21 13:54:45,487 - INFO  [main:QuorumPeerConfig@287] - Defaulting to majority quorums
2010-04-21 13:54:45,491 - FATAL [main:QuorumPeerMain@83] - Invalid config, exiting abnormally
org.apache.zookeeper.server.quorum.QuorumPeerConfig$ConfigException: Error processing /home/issei/app/zookeeper-3.3.0/bin/../conf/zoo.cfg
        at org.apache.zookeeper.server.quorum.QuorumPeerConfig.parse(QuorumPeerConfig.java:110)
        at org.apache.zookeeper.server.quorum.QuorumPeerMain.initializeAndRun(QuorumPeerMain.java:99)
        at org.apache.zookeeper.server.quorum.QuorumPeerMain.main(QuorumPeerMain.java:76)
Caused by: java.lang.IllegalArgumentException: /home/issei/tmp/zookeeper/myid file is missing
        at org.apache.zookeeper.server.quorum.QuorumPeerConfig.parseProperties(QuorumPeerConfig.java:297)
        at org.apache.zookeeper.server.quorum.QuorumPeerConfig.parse(QuorumPeerConfig.java:106)
        ... 2 more
Invalid config, exiting abnormally

ログをみると、/home/issei/tmp/zookeeper/myid file is missingと言われていることがわかります。
この場合、myid ファイルを用意してください。

  • 動作確認3(びっくりした編)

myid を用意して、myhdfs1 で ZooKeeper サーバを起動したところ、以下のようなログが定期的に・・・

2010-04-21 14:03:56,831 - INFO  [Thread-1:QuorumCnxManager$Listener@436] - My election bind port: 3888
2010-04-21 14:03:56,856 - INFO  [QuorumPeer:/0:0:0:0:0:0:0:0:2181:QuorumPeer@610] - LOOKING
2010-04-21 14:03:56,860 - INFO  [QuorumPeer:/0:0:0:0:0:0:0:0:2181:FastLeaderElection@649] - New election. My id =  1, Proposed zxid = 13
2010-04-21 14:03:56,871 - WARN  [WorkerSender Thread:QuorumCnxManager@361] - Cannot open channel to 2 at election address myhdfs2/172.29.11.112:3888
java.net.ConnectException: Connection refused
        at sun.nio.ch.Net.connect(Native Method)
        at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:507)
        at java.nio.channels.SocketChannel.open(SocketChannel.java:146)
        at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.java:347)
        at org.apache.zookeeper.server.quorum.QuorumCnxManager.toSend(QuorumCnxManager.java:320)
        at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.process(FastLeaderElection.java:353)
        at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.run(FastLeaderElection.java:326)
        at java.lang.Thread.run(Thread.java:619)
... 続く ...

よくよくみると、myhdfs2 へ接続しようとしている感じです。
※この時点で、myhdfs1 上でしか ZooKeeper を起動していない。

  • 動作確認4(気を取り直して編)

というわけで、myhdfs1/myhdfs2/myhdfs3 を連続で起動してみることにする。
myhdfs1 ⇒ myhdfs2 ⇒ myhdf3 の順番で、bin/zkServer.sh startを実行したところ、タイミングの違いで myhdfs1/myhdfs2 では前述の警告(WARN)が表示されましたが、最後に起動した myhdfs3 では警告は出ませんでした。


起動後の各サーバの jps の結果を以下に。

myhdfs1> jps
17497 NameNode
17753 SecondaryNameNode
17946 TaskTracker
20834 Jps
17825 JobTracker
17613 DataNode
20792 QuorumPeerMain

QuorumPeerMain というのが起動していることがわかります。

myhdfs2> jps
30593 DataNode
32754 Jps
32716 QuorumPeerMain
30698 TaskTracker

こちらも。

myhdfs3> jps
13679 Jps
11815 DataNode
11914 TaskTracker
13635 QuorumPeerMain

こちらも。


というわけで、見た目上は、ZooKeeper クラスタが起動したように思える。

  • 動作確認5(クライアントから接続してみる編)

で、クライアントから接続してみる。


まずは myhdfs1 から、サーバをローカルとして接続を試みる。
以下、接続してls /してquitするという単純な接続確認。

myhdfs1> cd ~/app/zookeeper
myhdfs1> ./bin/zkCli.sh -server myhdfs1
Connecting to myhdfs1
2010-04-21 14:16:34,111 - INFO  [main:Environment@97] - Client environment:zookeeper.version=3.3.0-925362, built on 03/19/2010 18:38 GMT
2010-04-21 14:16:34,117 - INFO  [main:Environment@97] - Client environment:host.name=xxx.yyy.zzz
2010-04-21 14:16:34,118 - INFO  [main:Environment@97] - Client environment:java.version=1.6.0_18
... ログ ...
2010-04-21 14:16:34,238 - INFO  [main-SendThread(myhdfs1:2181):ClientCnxn$SendThread@908] - Socket connection established to myhdfs1/172.29.11.201:2181, initiating session
2010-04-21 14:16:34,262 - INFO  [main-SendThread(myhdfs1:2181):ClientCnxn$SendThread@701] - Session establishment complete on server myhdfs1/172.29.11.111:2181, sessionid = 0x1281ec516d70001, negotiated timeout = 30000

WATCHER::

WatchedEvent state:SyncConnected type:None path:null
[zk: myhdfs1(CONNECTED) 0] ls /
[zookeeper]
[zk: myhdfs1(CONNECTED) 1] quit
Quitting...
2010-04-21 14:16:53,440 - INFO  [main:ZooKeeper@538] - Session: 0x1281ec516d70001 closed
myhdfs1>

大丈夫のようです。


次に、myhdfs1 から myhdfs3 をサーバに指定してつないで見ます。

myhdfs1> ./bin/zkCli.sh -server myhdfs3
Connecting to myhdfs3
2010-04-21 14:19:58,475 - INFO  [main:Environment@97] - Client environment:zookeeper.version=3.3.0-925362, built on 03/19/2010 18:38 GMT
... ログ... 
[zk: myhdfs3(CONNECTING) 0] 2010-04-21 14:19:58,684 - INFO  [main-SendThread(myhdfs3:2181):ClientCnxn$SendThread@701] - Session establishment complete on server myhdfs3/172.29.11.113:2181, sessionid = 0x3281ec4fd4b0000, negotiated timeout = 30000

WATCHER::

WatchedEvent state:SyncConnected type:None path:null

[zk: myhdfs3(CONNECTED) 0] ls /
[zookeeper]
[zk: myhdfs3(CONNECTED) 1] quit
Quitting...
2010-04-21 14:20:03,936 - INFO  [main:ZooKeeper@538] - Session: 0x3281ec4fd4b0000 closed
myhdfs1>

大丈夫のようです。


念のため、myhdfs2 から myhdfs3 に接続し、create /zk_test my_dataをしてみます。

myhdfs2> ./bin/zkCli.sh -server myhdfs3
Connecting to myhdfs3
2010-04-21 14:21:36,015 - INFO  [main:Environment@97] - Client environment:zookeeper.version=3.3.0-925362, built on 03/19/2010 18:38 GMT
... ログ ...
Welcome to ZooKeeper!
2010-04-21 14:21:36,189 - INFO  [main-SendThread(myhdfs3:2181):ClientCnxn$SendThread@701] - Session establishment complete on server myhdfs3/172.29.11.112:2181, sessionid = 0x3281ec4fd4b0001, negotiated timeout = 30000

WATCHER::

WatchedEvent state:SyncConnected type:None path:null
JLine support is enabled
[zk: myhdfs3(CONNECTED) 0] ls /
[zookeeper]
[zk: myhdfs3(CONNECTED) 1] create /zk_test my_data
Created /zk_test
[zk: myhdfs3(CONNECTED) 2] ls /
[zookeeper, zk_test]
[zk: myhdfs3(CONNECTED) 3] get /zk_test
my_data
cZxid = 0x100000008
ctime = Wed Apr 21 14:22:07 JST 2010
mZxid = 0x100000008
mtime = Wed Apr 21 14:22:07 JST 2010
pZxid = 0x100000008
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 0
[zk: myhdfs3(CONNECTED) 4] delete /zk_test
[zk: myhdfs3(CONNECTED) 5] ls /
[zookeeper]
[zk: myhdfs3(CONNECTED) 6] quit
Quitting...
2010-04-21 14:22:10,458 - INFO  [main:ZooKeeper@538] - Session: 0x3281ec4fd4b0001 closed
myhdfs2>

というわけで、一通り大丈夫のようです。

  • 動作確認6(こうするとどうなる?編)

クラスタということで、myhdfs1 に接続して /zk_test を作成し、別のクライアントから myhdfs3 に接続して /zk_test を参照してみます。
myhdfs2 から myhdfs1 に接続し、/zk_test を作成

[zk: myhdfs1(CONNECTED) 1] ls /
[zookeeper]
[zk: myhdfs1(CONNECTED) 2] create /zk_test my_data
Created /zk_test
[zk: myhdfs1(CONNECTED) 3] ls /
[zookeeper, zk_test]
[zk: myhdfs1(CONNECTED) 4] get /zk_test
my_data
cZxid = 0x10000000c
ctime = Wed Apr 21 14:32:38 JST 2010
mZxid = 0x10000000c
mtime = Wed Apr 21 14:32:38 JST 2010
pZxid = 0x10000000c
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 0

この状態で、myhdfs1 から myhdfs3 に接続し、/zk_test を get してみると

[zk: myhdfs3(CONNECTED) 0] get /zk_test
my_data
cZxid = 0x10000000c
ctime = Wed Apr 21 14:32:38 JST 2010
mZxid = 0x10000000c
mtime = Wed Apr 21 14:32:38 JST 2010
pZxid = 0x10000000c
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 0

とれますねー。ctime/mtime あたりが同じなので、同じなのでしょう。
というわけで、/zk_test を delete して動作確認は完了ということで。

  • 動作確認7(ステータス確認編)

マニュアルで、zoo.cfg のサーバ記述のところで、leaderを決めるとか書いてありましたが、zkServer.sh statusで確認できるようです。
コンソールにログがでるとやっぱりうっとうしいので、log4j.properties の rootLogger から CONSOLE を削除して再起動してみたときの例。


myhdfs2/myhdfs3 で zkServer.sh status を実行すると

myhdfs2> ./bin/zkServer.sh status
JMX enabled by default
Using config: /home/issei/app/zookeeper-3.3.0/bin/../conf/zoo.cfg
Mode: follower

という感じで、Mode: followerとなります。
このとき、myhdfs1 でステータスを確認すると

myhdfs1> ./bin/zkServer.sh status
JMX enabled by default
Using config: /home/issei/app/zookeeper-3.3.0/bin/../conf/zoo.cfg
Mode: leader

となりました(邪魔なコンソールログは削除)。
それで、myhdfs3/myhdfs2/myhdfs1 の順番で log4j.properties を書き換えて再起動したところ、myhdfs1 が leader ではなくなっていました。

myhdfs1> ./bin/zkServer.sh status
JMX enabled by default
Using config: /home/issei/app/zookeeper-3.3.0/bin/../conf/zoo.cfg
Mode: follower

調べてみたところ、myhdfs3 が leader になっていました。


というわけで、leader が落ちると、ちゃんと引き継いでくれるということがわかりました。とさ。


以上、長くなりましたが、これでまた HBase に戻れます。

セットアップ

ZooKeeper もなんとなく動いたみたいなので、HBase を導入してみる。
Hadoop のエントリで、バージョンは 0.20.0 と書いたのが、実は 0.20.2 の間違いだったという話は内緒です(修正しました)。


HBaseトップページ:http://hadoop.apache.org/hbase/
HBase のバージョンは 0.20.3 になります(2010.04.21 ダウンロード)。


  • 注意(2010/04/26 追記)

どうも HBase に ZooKeeper が同胞されているので、インストールは不要とのこと・・・
何を見落としていたんだろ。残念。

  • インストール

ドキュメントのセットアップのところに明示されていませんが、ダウンロードして解凍という方向は変わらず。
今回のインストールディレクトリは /home/issei/app/hbase となります(hbase-0.20.3 を ln -s でリンク貼った感じ)。

  • 基本設定

conf/hbase-env.sh の JAVA_HOME を設定。

クラスタ環境にするためには、conf/hbase-site.xml に設定を記述する必要があるらしい。
疑似分散(pseudo distributed)用の設定があり、クラスタ(実分散?)については、疑似分散環境の設定+αとなるみたい。


で、疑似分散のほうですが、hbase-site.xml に hbase.rootdir というプロパティを定義する必要があるみたいです。
内容は以下のような感じ(設定例はオフィシャルから引用)。

<configuration>
  ...
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://localhost:9000/hbase</value>
    <description>The directory shared by region servers.
    </description>
  </property>
  ...
</configuration>

NameNode が動作しているマシン&ポート、ルートディレクトリを設定するようです。
が、NameNode が起動しているポートなんてわかりません・・・

  • 横道:NameNode のポートを調べる。

実験環境の Hadoop クラスタの master は myhdfs1 です。
というわけで、myhdfs1 で、試してみる。

myhdfs1> hadoop fs -ls hdfs://myhdfs1:9000/
10/04/21 11:00:52 INFO ipc.Client: Retrying connect to server: myhdfs1/172.29.11.111:9000. Already tried 0 time(s).
10/04/21 11:00:53 INFO ipc.Client: Retrying connect to server: myhdfs1/172.29.11.111:9000. Already tried 1 time(s).
... 続く ...
10/04/21 11:01:01 INFO ipc.Client: Retrying connect to server: myhdfs1/172.29.11.111:9000. Already tried 9 time(s).
ls: Call to myhdfs1/172.29.11.111:9000 failed on connection exception: java.net.ConnectException: Connection refused

というわけで、ダメじゃん。
っていうか、デフォルトはどうよ?というわけで、ポートを外してみる。

myhdfs1> hadoop fs -ls hdfs://myhdfs1/
Found 2 items
drwxr-xr-x   - issei supergroup          0 2010-04-20 10:42 /hdhome
drwxr-xr-x   - issei supergroup          0 2010-04-21 09:48 /tmp

あっけなく成功。
ちなみに、この接続ができるのは master ノードのみみたいです。
例えば、myhdfs1(master)から

myhdfs1> hadoop fs -ls hdfs://myhdfs2/

としても、ポート9000を指定したときと同じ Connection refused のエラーとなります。
ならローカルなら?というわけで、myhdfs2(slave)で、同じく

myhdfs2> hadoop fs -ls hdfs://myhdfs2/

としてみましたが、ダメでした(myhdfs2 で hdfs://myhdfs1/ はアクセス可能)。


じゃぁ、元の設定のほうに戻って・・・と書こうとしたところで、デフォルトのポートってわかってないじゃん、というのに気がつきました。
ダメだったという、myhdfs1 から hdfs://myhdfs2/ へアクセスしようとすると

myhdfs1> hadoop fs -ls hdfs://myhdfs2/
10/04/21 11:02:59 INFO ipc.Client: Retrying connect to server: myhdfs2/172.29.11.112:8020. Already tried 0 time(s).
10/04/21 11:03:00 INFO ipc.Client: Retrying connect to server: myhdfs2/172.29.11.112:8020. Already tried 1 time(s).
...

という感じになります。あぁ、デフォルトのポートは 8020 なのね、というのがこれでわかります。

というわけで、疑似分散環境の設定を、以下のようにしました(まずは myhdfs1 の hbase-site.xml のみ)。

... 省略 ...
<configuration>
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://myhdfs1/hbase</value>
    <description>The directory shared by region servers.</description>
  </property>
</configuration>

デフォルトは何も設定されていない(<configuration>は空)なので、上記 property のブロックを追加する感じです。
ドキュメントにも記述されていますが、hbase.rootdir に localhost を指定すると、リモートから接続ができないそうです。なので、リモートから接続させる場合は(たぶん)上記のように名前で指定する必要があると思います。

というわけで、場所を用意(ディレクトリでいいのか?)

myhdfs1> hadoop fs -ls /
Found 2 items
drwxr-xr-x   - issei supergroup          0 2010-04-20 10:42 /hdhome
drwxr-xr-x   - issei supergroup          0 2010-04-21 09:48 /tmp
myhdfs1> hadoop fs -mkdir /hbase
myhdfs1> hadoop fs -ls /
Found 3 items
drwxr-xr-x   - issei supergroup          0 2010-04-21 11:24 /hbase
drwxr-xr-x   - issei supergroup          0 2010-04-20 10:42 /hdhome
drwxr-xr-x   - issei supergroup          0 2010-04-21 09:48 /tmp


分散環境(疑似ではなく)で実行する場合、hbase.rootdir に加えて、hbase.cluster.distributed という設定を true にする必要があります。
今回の実験環境では以下のようになりました。

... 省略 ...
<configuration>
  <!-- Pseudo-distributed mode setting -->
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://myhdfs1/hbase</value>
    <description>The directory shared by region servers.</description>
  </property>

  <!-- Fully-Distributed Operation setting -->
  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
    <description>The mode the cluster will be in. ... 省略 ...
    </description>
  </property>

</configuration>

ドキュメントのほうにも、分散環境にする場合、hbase.rootdir を localhost から NameNode が動作しているサーバ名に変更する必要があるって書いてますね。

分散環境で実行する場合、conf/regionservers(resionserver file)というファイルも変更する必要があります。
このファイルには、HRegionServers が動作しているホストを記述する必要があります(1行1ホスト)。これは Hadoop における slave 設定ファイル(Hadoop の conf/slaves)に近いイメージ。
デフォルトは localhost のみが記述されています。

myhdfs1> cat conf/regionservers
localhost

というわけで、これを以下のように修正しました。

myhdfs1> cat regionservers
myhdfs1
myhdfs2
myhdfs3


ここまで書いて、ZooKeeper のクラスタ化のエントリを書いたのですが。
分散 HBase (もう用語を統一するのがめんどくさくなってきた)は、ZooKeeper クラスタに依存します(ということがわかったので ZooKeeper をクラスタ化したとも言ふ)。


ZooKeeper を HBase に管理させることもできるようなので、その方向にしてみます。
ドキュメントをみると、ZooKeeper サーバが rs{1,2,3,4,5}.example.com のポート2222(デフォルトは 2181)で起動しているケースについてかかれています。


conf/hbase-env.sh の HBASE_MANAGES_ZK を true(デフォルトはコメントアウト)にする。

myhdfs1> grep HBASE_MANAGES_ZK hbase-env.sh
# export HBASE_MANAGES_ZK=true
export HBASE_MANAGES_ZK=true

コメントアウトを残しつつ、行コピーしてコメントアウトを外した感じ。


conf/hbase-site.xml に ZooKeeper の設定を追加。

...
 <configuration>
    ...
    <property>
      <name>hbase.zookeeper.property.clientPort</name>
      <value>2222</value>
      <description>Property from ZooKeeper's config zoo.cfg.
      The port at which the clients will connect.
      </description>
    </property>
    ...
    <property>
      <name>hbase.zookeeper.quorum</name>
      <value>rs1.example.com,rs2.example.com,rs3.example.com,rs4.example.com,rs5.example.com</value>
      <description>Comma separated list of servers in the ZooKeeper Quorum.
      ... 略 ...
      </description>
    </property>
    ...
  </configuration>
...

というわけなので、今回はサーバは myhdfs1/myhdfs2/myhdfs3 の3つ、ポートはデフォルト 2181 なので定義せず、というわけで以下のように追記。

<configuration>
  <!-- Pseudo-distributed mode setting -->
  ...

  <!-- Fully-Distributed Operation setting -->
  ...

  <!-- ZooKeeper's settings -->
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>myhdfs1,myhdfs2,myhdfs3</value>
    <description>Comma separated ... </description>
  </property>

</configuration>


以上をもって準備はOKみたいなのですが、まぁ、普通はすんなりはいかないだろうと思いつつ、まずは起動してみる(注意:いろいろあるので実際試される方がいましたら、最後のほうまでざっと目を通してから実行することをオススメします)。
起動の順序としては、HDFS、ZooKeeper、HBase の順(落とすのは逆)のようですが、HDFS と ZooKeeper はすでに起動済みなので、HBase のみ起動してみる。なお、起動は master となるサーバだけで良いみたいです(slaveのほうは勝手に起動されます)。
ちなみに、hbase-env.sh と hbase-site.xml の設定については、myhdfs1/myhdfs2/myhdfs3 ともに反映済みの状態となっています。
実行は、myhdfs1 にて、bin/start-hbase.sh を実行です。

myhdfs1> ./bin/start-hbase.sh
myhdfs3: starting zookeeper, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-zookeeper-myhdfs3.xxx.yyy.zzz.out
myhdfs1: starting zookeeper, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-zookeeper-myhdfs1.xxx.yyy.zzz.out
myhdfs2: starting zookeeper, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-zookeeper-myhdfs2.xxx.yyy.zzz.out
starting master, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-master-myhdfs1.xxx.yyy.zzz.out
myhdfs1: starting regionserver, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-regionserver-myhdfs1.xxx.yyy.zzz.out
myhdfs3: starting regionserver, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-regionserver-myhdfs2.xxx.yyy.zzz.out
myhdfs2: starting regionserver, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-regionserver-myhdfs3.xxx.yyy.zzz.out
myhdfs1> jps
17497 NameNode
17753 SecondaryNameNode
17946 TaskTracker
22225 HRegionServer
17825 JobTracker
17613 DataNode
21322 QuorumPeerMain
22311 Jps
22129 HMaster

という感じで、見た目上は特にエラーもなく、jps で確認したところ HMaster と HRegionServer なるものが起動していることがわかる。
同じく、myhdfs2/myhdfs3 で jps を実行してみると、HRegionServer が起動していた。

myhdfs2> jps
1548 HRegionServer
1624 Jps
30593 DataNode
714 QuorumPeerMain
30698 TaskTracker
myhdfs3> jps
13945 QuorumPeerMain
14692 Jps
14633 HRegionServer
11815 DataNode
11914 TaskTracker

これで起動したんですかねー?


ログをみてみると、どうもエラーが発生しているっぽい。
ログはインストールディレクトリ(/home/issei/app/hbase/)に logs というディレクトリが作成され、そこにログが出力されます。ので、そこで grep -i Exception * を実行すると Exception が発生したかどうかはわかります(※ ZooKeeper において起動順序によるコネクション失敗があるので、必ずしもすべてがエラーというわけではなさそうです)。
というわけで、いったんすべてシャットダウンしてみる。

  • 再度起動してみる:

というわけで、HDFS 以外をすべてシャットダウンさせる。
ZooKeeper の扱いがよくわからないので、 ZooKeeper を起動させたままだったのですが、そうすると

myhdfs1> ./bin/start-hbase.sh
myhdfs3: zookeeper running as process 15052. Stop it first.
myhdfs1: zookeeper running as process 23108. Stop it first.
myhdfs2: zookeeper running as process 2250. Stop it first.
...

という感じで怒られたので、いったん全て落としてみることにしました。
シャットダウンは myhdfs1(master)で、bin/stop-hbase.sh を実行するのですが、なぜか myhdfs2/myhdfs3 の HRegionServer が落ちないため、kill -9 で HRegionServer のプロセスを落としました。


気を取り直して HBase を起動するわけですが、起動前の各サーバの jps の結果を以下に。

myhdfs1> pwd
/home/issei/app/hbase
myhdfs1> jps
17497 NameNode
17753 SecondaryNameNode
17946 TaskTracker
24675 Jps
17825 JobTracker
17613 DataNode
myhdfs2> jps
30593 DataNode
30698 TaskTracker
2926 Jps
myhdfs3> jps
15631 Jps
11815 DataNode
11914 TaskTracker



いざ、実行。myhdfs1(master)で、bin/start-hbase.sh を実行

myhdfs1> ./bin/start-hbase.sh
myhdfs3: starting zookeeper, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-zookeeper-myhdfs3.xxx.yyy.zzz.out
myhdfs1: starting zookeeper, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-zookeeper-myhdfs1.xxx.yyy.zzz.out
myhdfs2: starting zookeeper, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-zookeeper-myhdfs2.xxx.yyy.zzz.out
starting master, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-master-myhdfs1.xxx.yyy.zzz.out
myhdfs2: starting regionserver, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-regionserver-myhdfs2.xxx.yyy.zzz.out
myhdfs3: starting regionserver, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-regionserver-myhdfs3.xxx.yyy.zzz.out
myhdfs1: starting regionserver, logging to /home/issei/app/hbase/bin/../logs/hbase-issei-regionserver-myhdfs1.xxx.yyy.zzz.out

という感じで、エラーは特になしだが、最初に起動したときとログもほぼ同じなんですよね・・・
※xxx.yyy.zzz の部分は都合により修正しています

  • 動作確認してみる

ドキュメントのRunning and Confirming Your Installationに書かれているレベルというか、HBase Shell(?)で接続できるかどうかだけやってみる。
テーブルとか作るのは次回にまわそう。
bin/hbase というファイルがあるので、これに shell という引数をつけて実行。

myhdfs1> pwd
/home/issei/app/hbase
myhdfs1> ./bin/hbase     ※引数をつけないと Usage がでます
Usage: hbase <command>
where <command> is one of:
  shell            run the HBase shell
  master           run an HBase HMaster node
  regionserver     run an HBase HRegionServer node
  rest             run an HBase REST server
  thrift           run an HBase Thrift server
  zookeeper        run a Zookeeper server
  migrate          upgrade an hbase.rootdir
 or
  CLASSNAME        run the class named CLASSNAME
Most commands print help when invoked w/o parameters.
myhdfs1> ./bin/hbase shell
HBase Shell; enter 'help<RETURN>' for list of supported commands.
Version: 0.20.3, r902334, Mon Jan 25 13:13:08 PST 2010
hbase(main):001:0> help
HBASE SHELL COMMANDS:
 alter     Alter column family schema;  pass table name and a dictionary
           specifying new column family schema. Dictionaries are described
           below in the GENERAL NOTES section.  Dictionary must include name
           of column family to alter.  For example,
... ヘルプの内容がずらっと続く ...
This HBase shell is the JRuby IRB with the above HBase-specific commands added.
For more on the HBase Shell, see http://wiki.apache.org/hadoop/Hbase/Shell
hbase(main):002:0> exit
myhdfs1>

hbase(main):001:0>コマンドプロンプトです。./bin/hbase shellを実行してからプロンプトが返ってくるまでちょっと時間がかかったのですが、大丈夫そう・・・なのかな?
今回は単に接続して help 実行して exit で抜けただけですが、一応 myhdfs1/myhdfs2/myhdfs3 すべてにおいて、./bin/hbase shell で接続できるところまで確認。

  • HDFS上はどうなってる?

そういえば、hbase-site.xml に HBase が使うディレクトリ(hdfs://myhdfs1/hbase)を設定したなぁ、というのを思い出したのでみてみた。

myhfds2> hadoop fs -ls /hbase
Found 4 items
drwxr-xr-x   - issei supergroup          0 2010-04-21 16:28 /hbase/-ROOT-
drwxr-xr-x   - issei supergroup          0 2010-04-21 15:52 /hbase/.META.
drwxr-xr-x   - issei supergroup          0 2010-04-21 16:28 /hbase/.logs
-rw-r--r--   3 issei supergroup          3 2010-04-21 15:52 /hbase/hbase.version

ファイル、できてますね。
だから何?というわけではありませんが。一応、できてますねー的な話。


以上、続きは次回ということで・・・