記録帳

クラウド、データ分析、ウイスキーなど。

HBase触ってみた

皆さんこんばんは。花粉が舞いに舞っている昨今、いかがお過ごしでしょうか。 春といえば、OSSのDBが恋しくなります。ということで、HBaseを今日一日触っていたので、その記録を書こうかと思います。

というのも、オライリーのデータ指向アプリケーションデザインの第6章「パーティション」を読んでいて、実際にプロダクトを触りたくなってきたからです。
データを分散して分けた1つ1つをパーティションと呼び、それをどのように分けるか?はたまたどのようにリバランシングするか?
などが載っていました。概念は理解しましたが、実際に実装だとどういう感じなのか理解したかった次第です。

HBaseとは?

f:id:supa25:20220403193925p:plain
hbase_logo

  • ApacheOSSのプロダクトのうちの1つ。
  • HDFS(Hadoop Distributed File System)上に構築するデータベース。
  • NoSQLの中のワイドカラム型に属する。
    • キーバリュー型の拡張。1つのキーに対して複数の列を持つことができる。
  • Regionという単位でデータを分散して持つ。そしてそのRegionをスレーブノードに割り当てる。
    • スレーブノードは他のPC1台に当たる。つまり、PC1台を追加する(スレーブノードを追加する)と、Regionが新たに割り当てられてスケールアップする。

HBaseの概要とアーキテクチャ | Think IT(シンクイット)
ここを読めばかなり詳しくわかります。
いわゆるMPP(Massively Parallel Processing)はRDBMSが並列処理を可能にしたものだけど、それとはまた別流派の分散DBといった感じでしょうか。
とにかく、パーティションを実現できるOSSなので、HBaseを今回は触ってみたいと思います。

HBaseのインストール

環境

Windows10
Docker version 20.10.5
docker-compose version 1.29.0

上記のWindows端末で実行していきます。

DockerでHBaseのコンテナ作成

① 資材をcloneしてくる
GitHub - big-data-europe/docker-hbase
上記のリポジトリをcloneしてきましょう。

Windowsでのgitのインストールはここなど詳しいです。
【Windows】Gitの環境構築をしよう! | プログラミングの入門なら基礎から学べるProgate[プロゲート]

ちなみに、以下の2つがdocker-composeファイルです。
今回は、分散処理させてみたかったので「distributed-local」の方を使います。
・docker-compose-distributed-local.yml
・docker-compose-standalone.yml

② ビルド実行
cloneした場所にPowerShellで移動して、以下を実行します。

docker-compose -f docker-compose-distributed-local.yml up -d

これでymlファイルに記載されているコンテナが複数ビルドされ、さらに立ち上がるはずです。
私はこれとは別にDocker Desktopも入れていますが、それ上ではこのように見えています。

f:id:supa25:20220403224725p:plain
docker_desktop

③ WEB UIで確認
http://localhost:16010 にアクセスしてみましょう。
上手くHBaseが立ち上がっていれば、以下のような画面になります。
(テーブルやRegion数はいじった後なので、立ち上げ直後とは異なると思います)

f:id:supa25:20220403225018p:plain
web_ui

参考

以下のページを参考にしました。
docker composeを使って「hbase」を構築するまでの手順 | mebee
HBaseのインストールと実行方法(スタンドアロンモード) - TASK NOTES

HBaseでのテーブル作成

テーブル作成、データ挿入

① コンテナログイン
マスターノードにログインします。「hbase-master」がマスターノードのクラスター名です。

docker exec -it hbase-master /bin/bash

② hbase-shell起動
(ここからはマスターノード上でコマンド実行します)
ログイン出来たら、以下のコマンドで対話型のコマンドラインツールを起動します。

hbase shell

次からは、このツール上でhbaseに色々なコマンドを打っていきます。

③ テーブル作成
create文でテーブルを作成します。
create 'テーブル名', 'ColumnFamily名' です。

create 'test_table', 'cf'

④ テーブル確認
WEB UI上で確認します。
以下のように、新しいテーブルができていれば成功です。
このテーブルは、Online Regionsがまだ1なので、分散されていない状態ですね。

f:id:supa25:20220403230121p:plain
create_table

⑤ データ挿入
put文でデータを挿入します。
put 'キー名', 'ColumnFamily名:Column名', 'バリュー' です。

put 'test_table', 'row1', 'cf:col1', 'value1'

このあたりの関係性は、以下のページが分かりやすいです。
HBaseのアーキテクチャを理解しよう (1/3):CodeZine(コードジン)

⑥ データ確認
WEB UI上で、Tableをクリックすると以下の画面に遷移します。
赤枠で囲っている、Requestsが1になっていればデータが挿入されています。
(「scan 'table名'」をhbase shellで打っても、データの内容は確認可能です)

f:id:supa25:20220403232247p:plain
data

HBaseでのパーティション確認

さて、ここからが本題。パーティションです。

事前パーティション

① 事前パーティションを定義してテーブル作成
以下のコマンドで、新しいテーブルを作成します。
今度は、キーの範囲でパーティションを切るように指定しています。

create 'test_table2', 'cf', SPLITS => ['1000','2000','3000','4000']

② 確認
WEB UIで確認します。
~1000 / 1000~2000 / 2000~3000 / 3000~4000 / 4000~
の5つのパーティションが作成されていることが分かります。

f:id:supa25:20220403232753p:plain
table_per

③ データを挿入
1000~2000のパーティションにデータを挿入してみます。
今回は、キーを'1234'にしてみましょう。

put 'test_table2', '1234', 'cf:col1', 'value1'

④ 確認
WEB UIで見ると、ちゃんと想定のパーティションのRequestsが1となっていますね。

f:id:supa25:20220403233049p:plain
table_per_2

パーティションの強制分割

ここでは、今5つに分けられているパーティションのうちの1つを強制的に分割してみます。
以下のページを参考にしています。(ちなみに、強制マージはできないそうです)
Apache HBase Region Splitting and Merging - Cloudera Blog

① 分割
ここでは、split文を用います。

split '8efadd362101393ea6e29e7cc7ee3fd0'

split 'encoded region name'
とすることで、指定のパーティションが分割されます。
'encoded region name'は、テーブル名とパーティションの開始の値(1000など)とtimestampのハッシュを取ってエンコードされたものだそうです。
参考:HBase hbckについて その1 - Qiita

'encoded region name'は、WEB UIだとここに表示されています。

f:id:supa25:20220403234234p:plain
split_region

② 確認
WEB UIで確認してみますが…
変化がないです。なぜかパーティションが分割されていませんね。
データ量が少なすぎた?少し大きいデータをいくつか挿入してみましょう。

③ データ挿入
以下のput文を、キーの値が1100, 1300, 1600, 1900の4種類ごとに10回打ちました。
100万文字は半角数字だったので、1回につき約1MBですね。
そのため、全部で40MBのデータを挿入した計算になります。

put 'test_table2', '1100', 'cf:col1', '[100万文字]'

さて、これでsplitを再度打ってみましょう。
(一応、split打つ前はこんな感じ。Requestsが44に増えてます)

f:id:supa25:20220404000033p:plain
split_mae

④ splitと確認
前と同じsplit文を打ちます。

split '8efadd362101393ea6e29e7cc7ee3fd0'

結果はこちら。

f:id:supa25:20220404000220p:plain
split_ato

見事に2つに分かれている…が、分割しているキーの範囲が何かおかしい?
1100, 1300, 1600, 1900に分けたので、1500くらいで分割されてくれると思いましたが。。
これは原因不明です。わかる方いたら教えてください。

自動パーティション分割

こちらは、HBaseのver0.94以降では、
Min (R2 * “hbase.hregion.memstore.flush.size”, “hbase.hregion.max.filesize”)
この式を超えると自動で分割されるそうです。
この2つは設定値で変更可能です。
・"hbase.hregion.memstore.flush.size”
・“hbase.hregion.max.filesize”
また、Rは同じテーブル内の現在のリージョンの数。
例えば、まだ1個しかリージョンが割当てられていない状態で、"hbase.hregion.memstore.flush.size”が128MBだとすると、その時は128MBを超えたら分割されます。
次は、2個割り当てられているのでRは2です。そのため、22 * 128MB=512MB を超えたら分割されます。

本当はこれを試してみたかったですが、このサイズのデータを挿入するのがかなりしんどいため見送りました。
どなたかやってみてください。

まとめ

  • HbaseはOSSの分散データベース。
  • docker-composeを使って簡単に構築可能。
  • テーブル作成の際にパーティションを指定できる。
  • splitコマンドで強制的に分割できる。
  • 自動分割も可能。設定値を変更すれば閾値も変えられる。

OSS知識欲が出てきたため、Sparkなども触ってみたいですね。
それでは。