HBase スタンドアローン・疑似分散環境の構築


HBaseの環境は以下の3つ

- スタンドアローンモード
- 疑似分散ローカル
- 完全分散環境

HBaseを開発・学習目的で使用する場合は、スタンドアローンモードか疑似分散ローカル環境のいずれかになります。

今回は、スタンドアローンモードと疑似分散ローカルの環境を構築してみます。
完全分散環境を構築する場合は、Cloudera CDHを利用するのが簡単だと思います。


# 環境

以下の環境で構築します。

- CentOS 7.5
- HBase v2.2.0


# スタンドアローンモードでのインストール

スタンドアローンモードは、HMaster, HRegionServer, ZooKeeperが1つのプロセス上で動作します。また、HDFSも利用せずローカルのファイルシステムに保存されます。


以下の公式のReference Guideを参考にインストールを実施しました。

- [2. Quick Start - Standalone HBase](https://hbase.apache.org/book.html#quickstart)

まず、サーバ上でHBaseのモジュール(v2.2.0)をダウンロードし、ファイルを展開します。

```
# wget http://ftp.jaist.ac.jp/pub/apache/hbase/2.2.0/hbase-2.2.0-bin.tar.gz
# tar xvf hbase-2.2.0-bin.tar.gz -C /opt
```

HBaseのモジュールのダウンロード先は以下のURLを参照してください。
https://www.apache.org/dyn/closer.lua/hbase/


# OpenJDKのインストール

HBaseではJDK8以上が必要なため、HBaseの起動前にインストールしておきます。

```
# yum install -y java-1.8.0-openjdk-devel

# java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-b04)
OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)

JAVA_HOMEを設定し、PATHにJavaのパスを追加しています。

# echo "export JAVA_HOME=$(readlink -e $(which java)|sed 's:/bin/java::')" > /etc/profile.d/java.sh
# echo "PATH=\$PATH:\$JAVA_HOME/bin" >> /etc/profile.d/java.sh
# source /etc/profile
```

HBaseではconf/hbase-env.shにJAVA_HOMEを設定することもできるそうです。複数のJDKがインストールされている場合は、hbase-env.shで使用するバージョンのJDKのJAVA_HOMEを設定すればよいかと思います。


# HBase構成ファイル（hbase-site.xml）の修正

HBase構成ファイルであるconf/hbase-site.xmlを編集します。

```
# vi /opt/hbase-2.2.0/conf/hbase-site.xml
```

サンプル設定ファイルを参考に以下のように記載しました。
HBaseとZooKeeperのデフォルトのデータ保存先が/tmp以下になっているので修正します。
重要なのはhbase.rootdir、hbase.zookeeper.property.dataDirです。
なお、これらのディレクトリはHBaseが自動で生成するため、事前に作成する必要はありません。

```
<configuration>
  <property>
    <name>hbase.rootdir</name>
    <value>file:///hbase</value>
  </property>
  <property>
    <name>hbase.zookeeper.property.dataDir</name>
    <value>/zookeeper</value>
  </property>
  <property>
    <name>hbase.unsafe.stream.capability.enforce</name>
    <value>false</value>
    <description>
      Controls whether HBase will check for stream capabilities (hflush/hsync).

      Disable this if you intend to run on LocalFileSystem, denoted by a rootdir
      with the 'file://' scheme, but be mindful of the NOTE below.

      WARNING: Setting this to false blinds you to potential data loss and
      inconsistent system state in the event of process and/or node failures. If
      HBase is complaining of an inability to use hsync or hflush it's most
      likely not a false positive.
    </description>
  </property>
</configuration>
```


# スタンドアローンモードで起動

設定が完了したら、以下のコマンドでHBaseを起動します。

```
# cd /opt/hbase-2.2.0/
# bin/start-hbase.sh
running master, logging to /opt/hbase-2.2.0/bin/../logs/hbase-root-master-hbaseserver1.out
```

HBaseのプロセスをjpsコマンドで確認すると、以下のようにHMasterのプロセス1つであることが確認できます。
これはスタンドアローンモードでは、HMaster, HRegionServer, ZooKeeperが1つのJVM上で起動していることを意味しています。

```
# jps
13108 Jps
12748 HMaster
```

hbase shellを使用してHBaseインスタンスに接続し、テーブルの作成、put, get等の各種操作を実行してみます。

まず、hbase shellを起動します。

```
# bin/hbase shell
2019-07-07 02:43:15,468 WARN  [main] util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
HBase Shell
Use "help" to get list of supported commands.
Use "exit" to quit this interactive shell.
For Reference, please visit: http://hbase.apache.org/2.0/book.html#shell
Version 2.2.0, rUnknown, Tue Jun 11 04:30:30 UTC 2019
Took 0.0033 seconds                                                                                                                                                                            
```

testテーブルを作成します。ColumnFamilyは"cf"を指定しています。

```
hbase(main):001:0> create 'test', 'cf'
Created table test
Took 1.4495 seconds                                                                                                                                                                           
=> Hbase::Table - test
```

テーブルの一覧を表示します。

```
hbase(main):002:0> list 'test'
TABLE                                                                                                                                                                                         
test                                                                                                                                                                                          
1 row(s)
Took 0.0368 seconds                                                                                                                                                                           
=> ["test"]
```

testテーブルの詳細を表示します。

```
hbase(main):003: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_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BL
OCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}                                                                                                   

1 row(s)

QUOTAS                                                                                                                                                                                        
0 row(s)
Took 0.3002 seconds                                                                                                                                                                           
```

putコマンドを用いて、テーブルにデータを挿入します。

```
hbase(main):004:0> put 'test', 'row1', 'cf:a', 'value1'
Took 0.0884 seconds                                                                                                                                                                           
hbase(main):005:0> put 'test', 'row2', 'cf:b', 'value2'
Took 0.0173 seconds                                                                                                                                                                           
hbase(main):006:0> put 'test', 'row3', 'cf:c', 'value3'
Took 0.0088 seconds                                                                                                                                                                           
```

scanコマンドを使用して、テーブルの全てのデータを取得します。

```
hbase(main):007:0> scan 'test'
ROW                                              COLUMN+CELL                                                                                                                                  
 row1                                            column=cf:a, timestamp=1562454057559, value=value1                                                                                           
 row2                                            column=cf:b, timestamp=1562454063102, value=value2                                                                                           
 row3                                            column=cf:c, timestamp=1562454068692, value=value3                                                                                           
3 row(s)
Took 0.0300 seconds                                                                                                                                                                           
```

getコマンドを使用して、指定した行を取得します。

```
hbase(main):008:0> get 'test', 'row1'
COLUMN                                           CELL                                                                                                                                         
 cf:a                                            timestamp=1562454057559, value=value1                                                                                                        
1 row(s)
Took 0.0251 seconds 
```

dropコマンドでテーブルを削除します。
削除する前に、disableコマンドで対象のテーブルを無効化しておく必要があります。

```
hbase(main):013:0> disable 'test'
Took 0.4524 seconds                                                                                                                                                                           
hbase(main):014:0> drop 'test'
Took 0.2754 seconds                                                                                                                                                                           
```

最後にstop-hbase.shスクリプトでHBaseを終了します。

```
# ./bin/stop-hbase.sh
stopping hbase.............
```


# 疑似分散ローカルでのインストール

疑似分散ローカルでは、スタンドアローンと同様にHBaseは1サーバ上で実行されます。
疑似分散ローカルとの違いは、各HBaseのプロセス（HMaster、HRegionServer、ZooKeeper）が別々のプロセスとして実行されること、およびデータの保存先としてHDFSを利用できるということです。

OpenJDKのインストールは完了した状態で実施しています。


## Hadoopのインストール

必須ではありませんが、今回はHDFSを利用したいのでHadoopをインストールします。

HBaseと同様にHadoopも疑似分散環境でインストールします。
インストール方法は以前、Sparkをインストールしたときの手順を以下に残しているので、その通りに実施しました。ということで手順は省略します。

-[Hadoopインストール](https://qiita.com/mkyz08/items/0c1d8fa47179933c3a56#hadoop%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

なお、上の手順ではhadoopユーザを使っていたので、スタンドアローンモードもhadoopユーザで実行するように変更しました。


次にhbase-site.xml設定を編集します。

```
# vi /opt/hbase-2.2.0/conf/hbase-site.xml
```

HBaseを分散モードで実行するように以下のプロパティを追加します。

```
<property>
  <name>hbase.cluster.distributed</name>
  <value>true</value>
</property>
```

次に、hbase.rootdirでローカルファイルシステムからHDFSのアドレスに変更します。

```
<property>
  <name>hbase.rootdir</name>
  <value>hdfs://localhost:8020/hbase</value>
</property>
  <property>
    <name>hbase.zookeeper.property.clientPort</name>
    <value>2181</value>
  </property>
```


# HBase起動

start-hbase.shでHBaseを起動します。
実行前に「start-dfs.sh」でHDFSを起動しておいてください。実行はhadoopユーザです。

```
# cd /opt/hbase-2.2.0/
# bin/start-hbase.sh 
```

jpsコマンドでプロセスを確認すると、スタンドアローンモードと比較してHMaster、HRegionServer、HQuorumPeerのプロセスが増えています（HQuorumPeerが何のプロセスなのか分かりませんが。。。）。


```
# jps
20432 NameNode
21761 Jps
20790 SecondaryNameNode
21207 HQuorumPeer
21481 HRegionServer
21340 HMaster
20542 DataNode
```

/base以下のファイルを見るとHBase起動により以下のファイルが生成されていることが分かります。

```
# /opt/hadoop/bin/hdfs dfs -ls /hbase
Found 13 items
drwxr-xr-x   - hadoop supergroup          0 2019-07-07 08:37 /hbase/.hbck
drwxr-xr-x   - hadoop supergroup          0 2019-07-07 08:37 /hbase/.tmp
drwxr-xr-x   - hadoop supergroup          0 2019-07-07 08:37 /hbase/MasterProcWALs
drwxr-xr-x   - hadoop supergroup          0 2019-07-07 08:37 /hbase/WALs
drwxr-xr-x   - hadoop supergroup          0 2019-07-07 08:37 /hbase/archive
drwxr-xr-x   - hadoop supergroup          0 2019-07-07 08:37 /hbase/corrupt
drwxr-xr-x   - hadoop supergroup          0 2019-07-07 08:37 /hbase/data
drwxr-xr-x   - hadoop supergroup          0 2019-07-07 08:37 /hbase/hbase
-rw-r--r--   1 hadoop supergroup         42 2019-07-07 08:37 /hbase/hbase.id
-rw-r--r--   1 hadoop supergroup          7 2019-07-07 08:37 /hbase/hbase.version
drwxr-xr-x   - hadoop supergroup          0 2019-07-07 08:37 /hbase/mobdir
drwxr-xr-x   - hadoop supergroup          0 2019-07-07 08:37 /hbase/oldWALs
drwx--x--x   - hadoop supergroup          0 2019-07-07 08:37 /hbase/staging
```