docker image を使って hbase-shell を実行してみるまで

#### 1.はじめに
Apache HBaseは Key-Value 型のデータベースです。
Hadoop プロジェクトの一部として開発され、HDFS (Hadoop Distributed File System)の上で実行されます。
本格的に使うためには、複数のノードからなる Hadoop クラスタの構築が必要となりますが、手元のローカル環境でお試しに実行してみることも可能です。
特に hbase-shell と呼ばれるツールは REPL (Read-Eval-Print-Loop) がベースになっており、表の作成や削除などの管理タスクを実行するコマンドラインツールです。

今回は、Apache HBase の Docker Image を使用し、ローカル環境で hbase-shell を実行していきます。
また、HBaseの実行環境は以下の3つありますが、hbase-shell を試す分には十分なスタンドアローンモードで実行していきます。

- スタンドアローンモード: 1台のマシン上でHDFS無
- 疑似分散ローカル : 1台のマシン上でHDFS有
- 完全分散環境 : 複数のマシン上でHDFS有

#### 2.（参考）実行環境
##### 2-1. docker と docker-compose がインストールされている
それぞれがインストールされていることが前提になります。

```bash
$ docker -v
Docker version 19.03.6, build 369ce74a3c
```

```bash
$ docker-compose -v
docker-compose version 1.17.1, build unknown
```

##### 2-2. スペック
メモリはトータルで8GB搭載されているマシンを使用しましたが、4GB程度でも問題なく動作します。

```bash
$ cat /etc/issue
Ubuntu 18.04.2 LTS
```

```bash
$ cat /proc/meminfo | grep Mem
MemTotal:        8168284 kB
MemFree:         6812556 kB
MemAvailable:    7545960 kB
```

#### 3. docker-compose の準備
以下のようなファイル(docker-compose.yml)を用意します。
ここでは、Apache HBase の docker image として、"blueskyareahm/hbase-base:2.1.3"、また zookeeper 用として、"blueskyareahm/hbase-zookeeper:3.4.13" を指定していますが、コンテナ起動時に各 Service を起動するためのスクリプトが実行されるようになっています。
これらのイメージは alpine:3.10 を元に作成しています。

```docker-compose.yml
version: '2'

services:
  hbase-master:
    image: blueskyareahm/hbase-base:2.1.3
    command: master
    ports:
      - 16000:16000
      - 16010:16010

  hbase-regionserver:
    image: blueskyareahm/hbase-base:2.1.3
    command: regionserver
    ports:
      - 16030:16030
      - 16201:16201
      - 16301:16301

  zookeeper:
    image: blueskyareahm/hbase-zookeeper:3.4.13
    ports:
      - 2181:2181
```
こちらの docker-compose.yml ファイルからは、hbase-master と hbase-regionserver、そして zookeeper それぞれ一つずつコンテナが生成されることになります。
それぞれのコンテナ（サービス）が成すHBaseのシステム構成は以下のようなイメージです。
![HBaseSystemConstitution.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/232572ea-7670-3036-ea1c-15161a1443e2.png)

#### 4. コンテナのビルド・開始
docker-compose.yml が配置されているディレクトリで以下のコマンドを実行します。

```bash
$ docker-compose up --build -d
Starting dockerhbase_hbase-regionserver_1 ... 
Starting dockerhbase_zookeeper_1 ... 
Starting dockerhbase_hbase-regionserver_1
Starting dockerhbase_zookeeper_1
Starting dockerhbase_hbase-master_1 ... 
Starting dockerhbase_hbase-regionserver_1 ... done
```

コマンドで確認すると、docker-compose.yml 内で指定した docker image がローカルにダウンロードされたことが確認できます。

```bash
$ docker images
REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE
blueskyareahm/hbase-base           2.1.3               bc85bf9cde47        6 days ago          394MB
blueskyareahm/hbase-zookeeper      3.4.13              b84eed2da9c6        6 days ago          150MB
```

また、hbase-master, hbase-regionserver, zookeeper それぞれ一つずつコンテナが起動されていることが確認できます。

```bash
$ docker ps
CONTAINER ID        IMAGE                                  COMMAND                  CREATED             STATUS              PORTS                                                                                                                                                  NAMES
55d31613504a        blueskyareahm/hbase-base:2.1.3         "/entrypoint.sh mast…"   5 days ago          Up About a minute   2181/tcp, 8080/tcp, 8085/tcp, 9090/tcp, 0.0.0.0:16000->16000/tcp, 9095/tcp, 16030/tcp, 16201/tcp, 16301/tcp, 0.0.0.0:16010->16010/tcp                  dockerhbase_hbase-master_1
69b00dbc3b83        blueskyareahm/hbase-base:2.1.3         "/entrypoint.sh regi…"   5 days ago          Up About a minute   2181/tcp, 8080/tcp, 8085/tcp, 9090/tcp, 9095/tcp, 16000/tcp, 0.0.0.0:16030->16030/tcp, 0.0.0.0:16201->16201/tcp, 16010/tcp, 0.0.0.0:16301->16301/tcp   dockerhbase_hbase-regionserver_1
0a9ac6fc557c        blueskyareahm/hbase-zookeeper:3.4.13   "/entrypoint.sh"         5 days ago          Up About a minute   3181/tcp, 0.0.0.0:2181->2181/tcp, 4181/tcp                                                                                                             dockerhbase_zookeeper_1
```

#### 5. hbase-shell の開始
以下のコマンドで hbase-shell を開始します。
今回は hbase-master コンテナ内の hbase-shell コマンドより開始しています。

```bash
$ docker-compose exec hbase-master hbase shell
--- 省略 ---
hbase(main):001:0>
```

#### 6. hbase-shell から操作してみる
##### ヘルプ表示
```bash
hbase(main):001:0> help
HBase Shell, version 2.1.3, rda5ec9e4c06c537213883cca8f3cc9a7c19daf67, Mon Feb 11 15:45:33 CST 2019
--- 省略 ---
The HBase shell is the (J)Ruby IRB with the above HBase-specific commands added.
For more on the HBase Shell, see http://hbase.apache.org/book.html
```

##### テーブルの作成
Table名(test) と ColumnFamily名('cf') を指定する必要があります。
 
```bash
hbase(main):002:0> create 'test', 'cf'
Created table test
Took 2.9629 seconds 
=> Hbase::Table - test
```

##### テーブルの存在確認
```bash
hbase(main):003:0> list 'test'
TABLE
test
1 row(s)
Took 0.1438 seconds
=> ["test"]

hbase(main):004:0> list 'dummy'
TABLE
0 row(s)
Took 0.0259 seconds
=> []
```

##### テーブルの一覧表示
```bash
hbase(main):005:0> list
TABLE
t1
test
2 row(s)
Took 0.0276 seconds
=> ["t1", "test"]
```

##### テーブルの構成確認
```bash
hbase(main):006:0> describe 'test'
Table test is ENABLED
test
COLUMN FAMILIES DESCRIPTION
{NAME => 'cf', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE
 => 'false', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRI
TE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true
', BLOCKSIZE => '65536'}
1 row(s)
Took 0.4172 seconds
```

##### データの挿入
それぞれの引数の意味が put 'テーブル名', 'キー', 'カラム名', 'データ' になります。

```bash
hbase(main):007:0> put 'test', 'row1', 'cf:a', 'value1'
Took 0.3695 seconds
hbase(main):008:0> put 'test', 'row2', 'cf:b', 'value2'
Took 0.0187 seconds
hbase(main):009:0> put 'test', 'row1', 'cf:c', 'value3'
Took 0.0236 seconds
```
この例では、row1 のキーに対しては2つのカラム('cf:a', 'cf:c')にデータを挿入しています。
row2 のキーに対しては、1つのカラム('cf:b')にデータを挿入しています。


##### テーブル内データの参照
'test' テーブル内の全データをスキャンしています。
row1 に2つ、row2 に1つのデータが挿入されていることが分かります。

```bash
hbase(main):010:0> scan 'test'
ROW               COLUMN+CELL
 row1             column=cf:a, timestamp=1596974012058, value=value1
 row1             column=cf:c, timestamp=1596974230499, value=value3
 row2             column=cf:b, timestamp=1596974204249, value=value2
2 row(s)
Took 0.0885 seconds
```

##### 特定の row のデータを取得
row(キー)を指定することで、特定の row のデータを取得できます。

```bash
hbase(main):011:0> get 'test', 'row1'
COLUMN               CELL
 cf:a                timestamp=1596974012058, value=value1
 cf:c                timestamp=1596974230499, value=value3
1 row(s)
Took 0.0780 seconds
```

##### テーブルの無効化
もしテーブルを削除したい場合、HBase ではそのテーブルをまず無効化する必要があります。

```bash
hbase(main):012:0> disable 'test'
Took 0.9336 seconds

hbase(main):014:0> describe 'test'
Table test is DISABLED
test
COLUMN FAMILIES DESCRIPTION
{NAME => 'cf', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE
 => 'false', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRI
TE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true
', BLOCKSIZE => '65536'}
1 row(s)
Took 0.0598 seconds
```

describe コマンドで確認すると、無効化(Table test is DISABLED) されていることが分かります。
有効化する場合は enable コマンドを使用します。

```bash
hbase(main):012:0> enable 'test'
```

##### テーブルの削除
テーブルが無効化されている状態で、drop コマンドを使います。

```bash
hbase(main):015:0> drop 'test'
Took 0.5828 seconds

hbase(main):016:0> list 'test'
TABLE
0 row(s)
Took 0.0087 seconds
=> []
```

##### hbase-shell の終了
```
hbase(main):017:0> exit
```

#### 7. さいごに

実運用上でデータの挿入や取得は、Javaなどのアプリケーションから行うことが主になると思われます。
テーブル上のデータの参照に関しても、大量のデータから何らかのフィルタ条件を元にデータを取得するには別途アプリケーションを用意した方が便利と思われます。

テーブルの作成や、開発中にテストデータを入れたり、その内容を確認する用として hbase-shell は便利なツールです。
Key-Value 型データベースである HBase を最初に学ぶ上で hbase-shell は手助けとなるシーンは多いと思います。
docker image を使用することで、最短5分ほどで hbase-shell 実行環境まで用意することができます。