どぅーちゅいむーにー

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

セットアップ

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

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


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