お仕事で HBase を使う事になったので環境構築から Ruby でアクセスするまでをやってみた。
HBase(スタンドアロンモード)をDockerで起動する
https://github.com/dajobe/hbase-docker にちょっと古いDockerfileがあったりするので使わせてもらった。
修正点1: Dockerfile
ENV HBASE_VERSION 0.94.11
→
ENV HBASE_VERSION 0.94.21
修正点2: start-hbase.sh
id=$(docker run -d -v $PWD/logs:/opt/hbase/logs -p :2181 -p :9090 -p :60000 -p :60020 dajobe/hbase)
→
id=$(docker run -d -v $PWD/logs:/opt/hbase/logs -p 2181:2181 -p 9090:9090 -p 60000:60000 -p 60020:60020 dajobe/hbase)
これで後は README.md に書かれた手順通り構築して起動する
$ docker build -t dajobe/hbase .
$ ./start-hbase.sh
Rubyのhbaserbでアクセスする
HBaseは色々なアクセス手段があるようだが、一番簡単そうだった Thrift 経由でアクセスしてみることにした。
ちなみに hbaserb をインストールする時に Mac だと Thrift のコンパイルで引っかかった。http://stackoverflow.com/questions/19649984/thrift-ruby-gem
#! /usr/bin/env ruby
# encode
require 'hbaserb'
client = HBaseRb::Client.new '192.168.59.103'
table = client.create_table "test", "fam1", "fam2"
table.mutate_row "1", {'fam1:hoge' => 'hoge', 'fam1:fuga' => 'fuga', 'fam2:count' => "1"}
table.mutate_row "2", {'fam1:hoge' => 'foo', 'fam1:fuga' => 'bar', 'fam2:count' => "1"}
注意: 僕の環境では DOCKER_HOST が 192.168.59.103 だ。
HBase がほかの KVS (memcached とか)と違う点としては、カラムファミリーという概念だろうか。テーブル生成時に、カラムファミリーというカラムを束ねる入れ物を指定しておく必要がある。この場合はfam1, fam2 を指定した。カラムは、fam1:hoge のようにカラムファミリーとコロンを頭に付ける必要がある。
これは hbaserb の問題かもしれないが、"1" のかわりに 1 を指定した場合はエラーが出た。
/Library/Ruby/Gems/2.0.0/gems/thrift-0.9.1/lib/thrift/bytes.rb:79:in `convert_to_utf8_byte_buffer': undefined method `encoding' for 1:Fixnum (NoMethodError)
自動的に to_s でもしてくれればいいのにとは思ったが、HBase ではデータ構造としては、ただのバイト列しかないらしいしそんなもんなんだろう。
#! /usr/bin/env ruby
# encoding: utf-8
require 'hbaserb'
client = HBaseRb::Client.new '192.168.59.103'
table = client.get_table "test"
row = table.get_row("1").first
p row.columns["fam1:hoge"].value
p row.columns["fam1:fuga"].value
p row.columns["fam2:count"].value
読み出すのはこんな感じ。get_row 以外にも get メソッドや、table の create_scanner メソッドなんかも使えるが hbaserb の lib/hbaserb 以下を見れば大体使い方はわかるだろう。