HBaseのデータ書き込みフロー Part 2

以前HBaseのデータ書き込みフローについて下記ブログを書きました。
HBaseのデータ書き込みフロー - wyukawa’s blog

どういう内容かというとHBaseでデータの書き込みを行う場合は、メモリ上のMemStoreに書き込むとともにディスク上のHLogにも書いて耐障害性を高め、最終的にはMemStoreがディスク上のHFileにフラッシュされるという話です。HFileの数が多くなってきた場合はコンパクションが実行されて複数のHFileがマージされます。

本エントリではHBaseのデータ書き込みについてもっと掘り下げてみたいと思います。

馬本でいうと「8.3 ライトアヘッドログ」辺りの話です。HBaseでいうライトアヘッドログ(Write Ahead Log。WALと略されることもあり)はHLogのことです。

Apache HBase Write Path - Cloudera Engineering Blogの図を参考にフローチャートっぽくHBaseのデータ書き込みフローを書くと以下のようになります。

さらに違った見方で図にするとこんな感じになります。馬本の図8-8を参考に書きました。

この図で言いたかったことはMemStoreとHLogが持つ情報量の違いですね。

HBaseのRegionServerは複数のRegionを持ちます。Region単位に存在するのがMemStoreになります。一方でRegionServer単位に存在するのがHLogです。

HLogがRegionServer毎にひとつなのは性能を重視しているためです。複数のHLogを持つようになったら大量のディスクシークが発生するからです。

HBase Clientから書き込みがあるとそれぞれ該当RegionのMemStoreにedits(馬本にあわせて書き込み単位をeditsと呼ぶ)が書き込まれます。しかしHLogはRegionServer毎に単一なのでHLogに書き込まれるeditsは複数のRegionのものが混在する形になります。

例えば1つのRegionServerに2つのRegion AとRegion Bがあって書き込みがそれぞれa1〜a5, b1〜b2まであってまだフラッシュされていない場合は下記のようになります。

フラッシュされていないのでHFileはRegion AとRegion Bともに空でHLogにはa1,b1,a2,a3,b2,a4,a5とある状態です。

Region Aのa1〜a5がフラッシュされると下記のようになります。MemStoreが空になってHFileに書き込まれます。


HLogがRegionServer毎に単一であるがゆえに起こる問題はToo many hlogsです。

ログには下記のように出るでしょう。

2012-03-29 07:44:32,758 INFO org.apache.hadoop.hbase.regionserver.wal.HLog: Too many hlogs: logs=33, maxlogs=32; forcing flush of 146 regions*(s):...

これはHLogの数が多くなりすぎてMemStoreが強制的にフラッシュされサーバーの負荷が上がるというものです。

これがなぜおこるかというとRegion毎に書き込みに差があるからです。

上記の例でいうとRegion Aには書き込みが多くてMemStoreがばんばんフラッシュされるのにRegion Bの書き込みが少ないためフラッシュされず結果としてHLogが削除できないということです。b1とb2がフラッシュされないのでHLogが削除できません。

HLogは一定時間経つとローリングされるわけですが、上記のように削除できないHLogがたまり続けると最終的には強制的なMemStoreのフラッシュが実行されサーバーの負荷がガツンと上がるというわけです。解決策としてはRegion毎の書き込みをうまくバランシングすることです。