7つのデータベース7つの世界 HBase メモ


# 環境
* CentOS 6.5
* Java 1.7.0
* HBase 0.98.5

# 1日目: CRUDとテーブル管理

## HBaseインストール
http://qiita.com/nownabe/items/11ca4744e3c85ed79bea

## 環境変数設定
やっとくと楽

```shell:~/.bash_profile
...

export JAVA_HOME=/usr/java/default
export HBASE_HOME="$HOME/7db/hbase/hbase-0.98.5-hadoop2"
export PATH=$HBASE_HOME/bin:$PATH
```

## プログラムからデータを追加する (p.98)

```ruby:put_multiple_columns.rb
include Java
import org.apache.hadoop.hbase.HBaseConfiguration
import org.apache.hadoop.hbase.client.HTable
import org.apache.hadoop.hbase.client.Put

def jbytes(*args)
  args.map {|arg| arg.to_s.to_java_bytes}
end

conf = HBaseConfiguration.create

table = HTable.new(conf, "wiki")

p = Put.new(*jbytes("Home"))

p.add(*jbytes("text", "", "Hello world"))
p.add(*jbytes("revision", "author", "jimbo"))
p.add(*jbytes("revision", "comment", "my first edit"))

table.put(p)
```

```bash
$ hbase org.jruby.Main put_multiple_columns.rb
```

## 1日目の宿題
### 調べてみよう
#### 1.
> シェルを使って以下のことをやる方法を見つけよう。
> 
> * 行にある特定の値を削除する
> * 行全体を削除する

http://learnhbase.wordpress.com/2013/03/02/hbase-shell-commands/

やってみようで挿入した行を削除してみます。

```ruby:hbase_shell
> get "wiki", "Some Title"
COLUMN                         CELL
 revision:author               timestamp=1408263446604, value=jschmoe
 revision:comment              timestamp=1408263446604, value=no comment
 text:                         timestamp=1408263446604, value=Some article text
3 row(s) in 0.0120 seconds

# ある行の特定の列を削除する
# delete table, row, column [, timestamp]
> delete "wiki", "Some Title", "revision:comment"
0 row(s) in 0.0240 seconds

> get "wiki", "Some Title"
COLUMN                         CELL
 revision:author               timestamp=1408263446604, value=jschmoe
 text:                         timestamp=1408263446604, value=Some article text
2 row(s) in 0.0050 seconds

# 行全体を削除する
# deleteall "wiki", "Some Title"
> deleteall "wiki", "Some Title"
0 row(s) in 0.0110 seconds

> get "wiki", "Some Title"
COLUMN                         CELL
0 row(s) in 0.0030 seconds
```

#### 2.
> 使っているバージョンのHBaseのAPIドキュメントをブックマークしてみよう。

0.95のは見つかりませんでした。0.94と一緒？

http://hbase.apache.org/0.94/apidocs/index.html

### やってみよう
#### 1. 
> Put インスタンスを生成するput_many()という関数を作ってみよう。列と値のペアをいくつか追加して、テーブルにコミットしてみよう。関数のシグニチャは以下のようにする。
>
> ```ruby
> def put_many( table_name, row, column_values )
>   # your code here
> end
> ```

```ruby:put_many.rb
include Java
import org.apache.hadoop.hbase.HBaseConfiguration
import org.apache.hadoop.hbase.client.HTable
import org.apache.hadoop.hbase.client.Put

class MyHBase
  def self.jbytes(*args)
    args.flatten.map {|arg| arg.to_s.to_java_bytes}
  end

  def self.conf
    HBaseConfiguration.create
  end

  def self.get_table(t)
    HTable.new(conf, t)
  end

  def self.put_many(table_name, row, column_values)
    t = get_table(table_name)
    p = Put.new(*jbytes(row))
    column_values.each do |col, val|
      arg = col.split(/:/)
      arg << "" if arg.size < 2
      arg << val
      p.add(*jbytes(arg))
    end
    t.put(p)
  end
end
```

#### 2.
> HBaseシェルにput_many()のコードをペーストして、関数を定義してみよう。

```ruby:hbase_shell
> require './put_many'
=> true
> MyHBase.put_many("wiki", "Some Title", {
  "text:" => "Some article text",
  "revision:author" => "jschmoe",
  "revision:comment" => "no comment"
})
```

# 2日目：ビッグデータを扱う
## Wikipediaのストリーミング

```bash:import_from_wikipedia.rb
nclude Java
import javax.xml.stream.XMLStreamConstants
import org.apache.hadoop.hbase.client.HTable
import org.apache.hadoop.hbase.client.Put
import org.apache.hadoop.hbase.HBaseConfiguration

def jbytes(*args)
  args.map {|arg| arg.to_s.to_java_bytes }
end

factory = javax.xml.stream.XMLInputFactory.newInstance
reader = factory.createXMLStreamReader(java.lang.System.in)

document = nil
buffer = nil
count = 0

conf = HBaseConfiguration.create
table = HTable.new(conf, "wiki")
table.setAutoFlush(false)

while reader.has_next
  type = reader.next
  if type == XMLStreamConstants::START_ELEMENT
    case reader.local_name
    when "page" then document = {}
    when /title|timestamp|username|comment|text/ then buffer = []
    end
  elsif type == XMLStreamConstants::CHARACTERS
    buffer << reader.text unless buffer.nil?
  elsif type == XMLStreamConstants::END_ELEMENT
    case reader.local_name
    when /title|timestamp|username|comment|text/
      document[reader.local_name] = buffer.join
    when "revision"
      key = document["title"].to_java_bytes
      ts = Time.parse(document["timestamp"]).to_i

      p = Put.new(key, ts)
      p.add(*jbytes("text", "", document["text"]))
      p.add(*jbytes("revision", "author", document["username"]))
      p.add(*jbytes("revision", "comment", document["comment"]))
      table.put(p)

      count += 1
      table.flushCommits() if count % 10 == 0
      if count % 500 == 0
        puts "#{count} records inserted (#{document["title"]})"
      end
    end
  end
end

table.flushCommits()
```

## 2日目の宿題
### 調べてみよう
1. HBaseにおける圧縮の利点と欠点について説明している記事を探してみよう。
  * http://open-groove.net/hbase/hbase-hdfs-blocksize/
  * http://oss.infoscience.co.jp/hbase/book/
  * http://www.mwsoft.jp/programming/hadoop/snappy_memo.htmlimportant_configurations.html#lzo
2. ブルームフィルタの動作とHBaseにおける利点について説明している記事を探してみよう。
  * http://sssslide.com/www.slideshare.net/tatsuya6502/apache-hbase-4630623#12
  * http://www.slideshare.net/kumagi/bloom-filter-4178952
3. 列ファミリーの圧縮に関するオプションを探してみよう（アルゴリズム以外）。
  * BLOCK
4. 列ファミリーの圧縮オプションにデータの種類や使用パターンを伝える方法を探してみよう。

# 3日目
## Thriftのインストール
これを参考にしました。
http://qiita.com/warlock-mw/items/c3dc916f14bb385053c1

Thriftのビルドは、

```bash
$ ./configure
$ make
$ make clean
$ make
$ make install
```

でいけました。

Gemは`thrift`の他に、`rack`と`thin`のインストールが必要でした。

## モデルを生成する
`HBase.thrift`がなかったので、こちらを使いました。
http://svn.apache.org/viewvc/hbase/trunk/hbase-thrift/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift?view=markup

## whirrの準備

```bash
$ wget http://ftp.tsukuba.wide.ad.jp/software/apache/whirr/stable/whirr-0.8.2.tar.gz
$ tar zxvf whirr-0.8.2.tar.gz
$ cd whirr-0.8.2
$ bin/whirr version
Apache Whirr 0.8.2
jclouds 1.5.8
$ mkdir keys
$ chmod 700 keys
$ ssh-keygen -t rsa -P '' -f keys/id_rsa
```

準備はしたんですが、whirrはクイックスタートすらうまく動かなかったので断念。
レポジトリみても最新の安定版が1年以上前のものなので諦めました。