HBase の環境が一応できたということで、まずは触ってみる。
ドキュメントとしては、Getting Started の他には API ドキュメント、Wikiと FAQ という感じらしい。
正直、Cassandra もそうだが、wiki がかなりわかりにくいと思う(探しにくいだけ?)。
ので、Shell を使ってアクセスし、help を実行したときに表示されるコマンドを1つずつ試してみることにします(できるものだけ)。
ちなみに、wiki で shell を検索したら、そのページは見つけました↓
http://wiki.apache.org/hadoop/Hbase/Shell
- 以下、実行しているコマンド
ざっと、試したコマンドを以下に。
- create:テーブルの作成
- list:テーブル一覧
- describe:テーブル情報の表示
- put:値の設定
- get:値取得
- scan:走査
- delete/deleteall:削除
- count:行カウント
- disable:テーブルの無効
- drop:テーブルの削除
- 一般的な点
まずはテーブル作成といきたいところですが、テーブル作成(create)の文法ででてくる「ディクショナリ」については GENERAL NOTES を参照ということなので、先に GENERAL NOTES を。
・テーブル名、カラム名はクォート(シングルクォートで囲う)すること
・カンマがコマンドパラメータのデリミタ(区切り文字)
・リターンを押下するとコマンドが実行される
・ディクショナリはテーブルの生成(creation)や変更?(alternation)で使われるディクショナリは Ruby における Hash のこと。
サンプルを以下に。
{'key1' => 'value1', 'key2' => 'value2', ...}
はじめと終わりは中カッコ(curley-braces)でくくる。key と value は '=>' で区切られる。
通常、キーは固定文字列を指定するわけですが、固定文字列の場合はクォートする必要はないようです。
'Object.constants' という表現で、その環境における定数を参照することができるようです(現時点でピンときませんが)。
・バイナリ形式の key または value を扱う場合、ダブルクォートを使って16進または8進表記する必要がある
hbase> get 't1', "key\x03\x3f\xcd"
hbase> get 't1', "key\003\023\011"
hbase> put 't1', "test\xef\xff", 'f1:', "\x01\x33\x40"
こんな感じでしょうか。
ダブルクォートを使って、shell コマンドの結果を value として設定するといったことができるような雰囲気なのですが、現時点ではちょっと置いておきます。
- テーブルを生成:create/list/describe
さっそくテーブルを作成。文法的なイメージはこんな感じでしょうか?
create テーブル名[, カラムファミリ]*
テーブル名の後、カラムファミリごとの定義をディクショナリで指定。
help にある実行例を以下に。
hbase> create 't1', {NAME => 'f1', VERSIONS => 5}
hbase> create 't1', {NAME => 'f1'}, {NAME => 'f2'}, {NAME => 'f3'}
hbase> # The above in shorthand would be the following:
hbase> create 't1', 'f1', 'f2', 'f3'
hbase> create 't1', {NAME => 'f1', VERSIONS => 1, TTL => 2592000, BLOCKCACHE => true}
ピンとこない部分もあるのですが、とりあえず、今回は次のようなテーブルを作成してみたいと思います。
テーブル名は people で。'name' も prop じゃん、という話はとりあえず置いておきます。
キー | prop:age | prop:occupation | test:abc |
---|---|---|---|
issei | 33 | SE | This is a pen. |
suzuki | 25 | Consultant | foo |
saito | 40 | Teacher | hoge |
というわけで特に何も考えず myhdsf2 で実行したのですが・・・
myhdfs2> ./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> create 'people', 'prop', 'test' NativeException: org.apache.hadoop.hbase.MasterNotRunningException: 127.0.0.1:60000
というわけで、怒られてしまいました・・・
そんなわけで、myhdfs1 で再チャレンジ。
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> create 'people', 'prop', 'test' 0 row(s) in 2.1520 seconds
今度は問題なく作られたようで。
テーブルの一覧を見てみる
hbase(main):007:0> list people 1 row(s) in 0.0120 seconds
できてますね(なかった状態はみてませんが・・・)。
テーブル定義を見てみる。
hbase(main):010:0> describe 'people' DESCRIPTION ENABLED {NAME => 'people', FAMILIES => [ {NAME => 'prop', COMPRESSION => 'NONE' true, VERSIONS => '3', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}, {NAME => 'test', COMPRESSION => 'NONE', VERSIONS => '3', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'} ]} 1 row(s) in 0.0440 seconds
細かい点はおいといて、prop と test というファミリが作成されている、ってことはわかります。
※実際の表示から整形しています。
- データを設定してみよう:put
データの設定はput
で行います。
文法的にはput テーブル名, 行キー, セル, 値[, タイムスタンプ]
となるようです。
テーブル、行、カラム(とオプションでタイムスタンプ)を指定して値を設定します。
テーブル t1 の r1 行のカラム c1 に、タイムスタンプ ts1 で 'value' を設定する場合は次のようなコマンドとなる。
hbase> put 't1', 'r1', 'c1', 'value', ts1
では、さっそく。
hbase(main):011:0> put 'people', 'issei', 'prop:age', '33' 0 row(s) in 0.0070 seconds hbase(main):012:0> put 'people', 'issei', 'prop:occupation', 'SE' 0 row(s) in 0.0090 seconds hbase(main):013:0> put 'people', 'issei', 'test:abc', 'This is a pen.' 0 row(s) in 0.0080 seconds
これで1行ぶんですね。
続けて suzuki と saito についても登録します。
hbase(main):014:0> put 'people', 'suzuki', 'prop:age', '25' 0 row(s) in 0.0100 seconds hbase(main):015:0> put 'people', 'suzuki', 'prop:occupation', 'Consultant' 0 row(s) in 0.0140 seconds hbase(main):016:0> put 'people', 'suzuki', 'test:abc', 'foo' 0 row(s) in 0.0080 seconds hbase(main):017:0> put 'people', 'saito', 'prop:age', '40' 0 row(s) in 0.0080 seconds hbase(main):018:0> put 'people', 'saito', 'prop:occupation', 'Teacher' 0 row(s) in 0.0120 seconds hbase(main):019:0> put 'people', 'saito', 'test:abc', 'hoge' 0 row(s) in 0.0080 seconds
- データ取得:get
行単位、セル単位で値が取得できるようです。文法的には
get テーブル名, 行[, カラムや条件]
という感じでしょうか。プログラムからアクセスする場合はもっと細かく指定できるのかもしれませんが。
people テーブルについていくつかやってみます。
hbase(main):021:0> get 'people', 'issei' COLUMN CELL prop:age timestamp=1271901645856, value=33 prop:occupation timestamp=1271901686162, value=SE test:abc timestamp=1271901702050, value=This is a pen. 3 row(s) in 0.0180 seconds hbase(main):022:0> get 'people', 'issei', {COLUMN => 'test:abc'} COLUMN CELL test:abc timestamp=1271901702050, value=This is a pen. 1 row(s) in 0.0140 seconds
タイムスタンプやバージョンについてはまだやっていないので、今回はパスということで。
ただ、help だとできるような感じで書かれている、複数カラム指定がNGになる・・・
タイプミスしてる?
hbase(main):026:0> get 'people', 'issei', {COLUMN => ['prop:age', 'test:abc']} NoMethodError: undefined method `to_java_bytes' for ["prop:age", "test:abc"]:Array
- 走査(?):scan
get
はキー指定のデータ取得なわけですが、scan はその名の通り(?)テーブルのデータを走査するためのものです。
文法的にはこんな感じでしょうか。
scan テーブル名[, 条件など]
条件など、のところには LIMIT(上限)、STARTROW(開始行)、STOPROW(終了行)、TIMESTAMP(タイムスタンプ。用途不明)、COLUMNS(走査対象カラム)を指定する感じです。
上述のテーブルにおいて、単に scan 'people' をするとこんな感じです。
hbase(main):005:0> scan 'people' ROW COLUMN+CELL issei column=prop:age, timestamp=1271901645856, value=33 issei column=prop:occupation, timestamp=1271901686162, value=SE issei column=test:abc, timestamp=1271901702050, value=This is a pen. saito column=prop:age, timestamp=1271901818772, value=40 saito column=prop:occupation, timestamp=1271901827465, value=Teacher saito column=test:abc, timestamp=1271901836594, value=hoge suzuki column=prop:age, timestamp=1271901775977, value=25 suzuki column=prop:occupation, timestamp=1271901787836, value=Consultant suzuki column=test:abc, timestamp=1271901804853, value=foo 3 row(s) in 0.0600 seconds
カラム指定(COLUMNS => 'prop:age')
hbase(main):007:0> scan 'people', { COLUMNS => ['prop:age']} ROW COLUMN+CELL issei column=prop:age, timestamp=1271901645856, value=33 saito column=prop:age, timestamp=1271901818772, value=40 suzuki column=prop:age, timestamp=1271901775977, value=25 3 row(s) in 0.0510 seconds
追加で LIMIT 指定
hbase(main):008:0> scan 'people', { COLUMNS => ['prop:age'], LIMIT => 2} ROW COLUMN+CELL issei column=prop:age, timestamp=1271901645856, value=33 saito column=prop:age, timestamp=1271901818772, value=40 2 row(s) in 0.0370 seconds
という感じになりました。
あとは用途によって、というところなので、現時点ではこれくらいにしておきます。
- セル/行の削除:delete/deleteall
次に削除。文法としては
delete テーブル名, キー, カラム
のようです。
saito さんの prop:occupation を削除してみます。
hbase(main):013:0> delete 'people', 'saito' ArgumentError: wrong # of arguments(2 for 3) hbase(main):014:0> delete 'people', 'saito', 'prop:occupation' 0 row(s) in 0.0140 seconds hbase(main):015:0> get 'people', 'saito' COLUMN CELL prop:age timestamp=1271901818772, value=40 test:abc timestamp=1271901836594, value=hoge 2 row(s) in 0.0200 seconds
予想通り、delete
の場合、カラムを指定しないと怒られました。
deleteall で saito さんの行を削除してみます。
hbase(main):017:0> deleteall 'people', 'saito' 0 row(s) in 0.0110 seconds hbase(main):018:0> get 'people', 'saito' COLUMN CELL 0 row(s) in 0.0060 seconds
こちらはテーブル名、キーのみでいけました。
- カウント:count
テーブル内の行数を数えてみる。とは言ってもたった2行(deleteallで削除したので)なので、面白みもないのですが。
hbase(main):019:0> count 'people' 2 row(s) in 0.0160 seconds
Hadoop の行数カウント MapReduce が実行される(?)からか、時間がかかることがあるそうです。
まぁ、現時点では・・・
- テーブルの削除とステータス変更:drop/disable
テーブルを削除(drop)する前には、disable にする必要がある、とあります。
ので、試してみる。
テーブルの状態は、describe テーブル名
としたときに表示されるようです。
hbase(main):024:0> describe 'people' DESCRIPTION ENABLED {NAME => 'people', FAMILIES => [{NAME => 'prop', COMPRESSION => 'NONE' true, ... 1 row(s) in 0.0420 seconds
この状態でdrop
を試みてみる。
hbase(main):027:0* drop 'people' IOError: Table people is enabled. Disable it first >|| ダメですね。 というわけで、disable にしてみる。 >|sh| hbase(main):028:0> disable 'people' 0 row(s) in 2.1020 seconds hbase(main):029:0> describe 'people' DESCRIPTION ENABLED {NAME => 'people', FAMILIES => [{NAME => 'prop', COMPRESSION => 'NONE' false, ... hbase(main):030:0> describe 'people'
んー。ENABLE のままですね・・・
まぁ、とりあえずこの状態でdrop
してみる。
hbase(main):031:0> drop 'people' 0 row(s) in 0.0130 seconds 0 row(s) in 0.0110 seconds 0 row(s) in 0.0880 seconds hbase(main):032:0> list 0 row(s) in 0.0210 seconds
よくわかりませんが、drop できたようです。describe のときの ENABLED は参考にならないんですかねー。
今のところ困るわけではないので、この件はまたの機会に。
enable を試す前に drop してしまったので、enable についてもまたの機会に。
というわけで、今回はこんなところで。