Hadoop HBase part2

ということで,HBaseについて.

最近,Hadoop内でも特に活発に開発されているHBaseについてです.これは,Google Bigtableの再実装ですね.HBase Architectureを読んでみたまとめを書いておきます.第2弾です.Client APIについては,JavaDoc読めとのこと.後回し.

HRegion (Tablet) Server
ユーザにとっては,普通のテーブルに見えるけど,内部的には,HRegionsに分かれています.HRegionは,テーブル名とstart/end key pairによって一意に決定されます.で,複数のHRegionServerを扱うことによって,ユーザは,データを利用できます.このとき,HRegionServerは,1台に1プロセス存在し,あるHRegionは一度に一つのHRegionServerしかアクセスできません.

ユーザがデータを更新するときには,(更新に)関連するHRegionServerへアクセスし,HRegionをコミットします.で,コミットの時点で,そのデータは,HRegionのHMemcacheとHRegionServerのHLogへ追加されます.HMemcacheは,メモリバッファであり,一番直近のデータをストア・管理します.HLogは,ディスク上にあって,全ての更新を追跡します.commit()関数は,更新がHLogに書かれるまで返り値を戻しません.

データを取り出すときには,まず,HRegionは,HMemcacheをチェックします.もしも,データが無い場合,ディスク上のHStoresをチェックします.一つのHRegion内に,それぞれのカラムファミリーに対してひとつのHStoreが存在します.HStore自信は,複数のHStoreFilesから構成されます.高速アクセスを目指すために,HStoreFileは,B-Treeライク構造を持っています.
定期的に,HRegion.flushcache()を呼び出して,HMemcacheにあるデータをHStoreのファイル群に書き込みます.このとき,新しいHStoreFileがそれぞれのHstoreへ追加されます(?なんで?).HMemcacheが空になったら,HLogにフラッシュされたことを示すトークンを書き込みます(チェックポイントだね).

起動時には,それぞれのHRegionは,HLogに何らかの書き込みがあったかどうかをチェックします(直近のflushcache()を調べます).もしなければ,全ての関連するHRegionのデータは,HStoreに書き込まれていることになります.もし,チェックポイント以降のデータがあれば,HLogから更新されたデータを再構築し,HMemcacheへそのデータを書いて,flushcache()を呼び出します.最後に,HLogを消してデータの利用が可能になります.#うん?HLogのデリートしちゃうのか?
そのようにして,flushcache()を少なく呼べば,仕事も少なくて済みます.しかし,HMemcacheは,より多くのメモリを消費し,再起動時の再構築作業が長くなります.もし,flushcache()を頻繁に呼べば,HMemcacheのメモリは少なくなり,HLogの再構築は早くなりますが,flushcache()はオーバヘッドを引き起こすことになります.

HLogは,定期的にローテションするので,複数の時系列的にソートされた複数のファイル.HLogをローテションするときには,HLogは,一番古いlog fileを削除します(当然フラッシュ済み).HLogのローテーションにかかる時間はとても短くて,継続的に行うには良い.flushcache()が呼び出されると,HStoreFileをHStoreへ追加します.なので,HStoreからフェッチするときには,これらのStoreFilesに一度にアクセスすることが可能になります.このこと自体は,時間がかかるので,定期的にこれらのHStoreFilesを一つの大きなファイルへコンパクト化します.これは,HStore.compact()によって実現されています.コンパクションの実行は重たいので,バックグラウンドで実行されます.HStoreFilesの数が設定された閾値を超えた場合に実行されます.

Bigtableのペーパーでは,major/minorコンパクションがあるけど,ちょっと複雑.以下のことに気をつけています.
1.flushcache()は,メモリバッファからあふれた全ての更新をディスクへ書き込みます.flushcache時に,log再構築時間はゼロにします.
各flushcache()は,新しいHStoreFileをそれぞれのHStoreへ追加します.
2.compact()は,全てのHStoreFilesを一つに統合します.
Bigtableと違って,HBaseでは,更新がコミットされたけれどもログにかかれていないという状態を許しません.ただまぁ,もし本当に必要であれば,この機能を追加するのは簡単です.HRegion.closeAndMerge()を用いて,二つのHRegionsを新しい一つのHRegionにマージすることが可能です.現時点では,これをやるときには,両方のregionがオフラインである必要があります.

regionが設定値よりも大きくなった場合,HRegion.closeAndSplit()が呼び出されます.親regionを分割することで新しい二つのregionが作られます.新しいregionsはマスタ(サーバ)へどのサーバがどの娘regionをホストするのかを通知します.分割は大抵高速ですが,その理由は,娘のrigionは,親regionのもつファイルへの参照を持つからです.一人目の娘は,上半分,二人目は,下半分を持ちます.この参照が配置される間,親regionはオフラインになり,コンパクションが終了し,親regionが取り除かれることになるまで,特に何もしません.

まとめてみますと,
1.クライアントはテーブルのデータにアクセスします
2.テーブルは,HRegionsへ分解されます.
3.HRegionsは,HRegionServerによって管理されます.クライアントは,サーバが持つレコード範囲にあるレコードにアクセスするため,
HRegionServerにアクセスします.
4.HRegtionは,データを以下に格納します.
4.1. HMemcache:最近書かれたデータのメモリバッファ
4.2. HLog:最近の書き込みに対する,書き込みログ
4.3.HStrore:ファイルの集合.カラムグループに一つ存在する.