Edited at

HBase 1.2で導入されたSimpleRegionNormalizerについて

More than 1 year has passed since last update.

Distributed computing (Apache Hadoop, Spark, ...) Advent Calendar 2016の二日目です。HBase 1.2で導入され、CDH 5.7以降に含まれるSimpleRegionNormalizerを紹介します。本記事で対象とするロジックはCDH 5.9.0とします。

さて、その名のとおりこれは非常にシンプルな機能で、定期的に指定されたテーブルの平均リージョンサイズをチェックし、(算術)平均から上下に大きく外れたサイズのリージョンをスプリット、あるいはマージすることでリージョンサイズの偏りを解消するものです。チェック間隔はデフォルトで5分(300000ms)、HMasterのhbase.normalizer.periodにてmsで明示的に指定することができます。

ただし、テーブル単位で動作するこのチェックはすべてのテーブルでデフォルト無効です。有効化するにはテーブルのプロパティで明示的に設定してやる必要があります。

> disable 'table_name'

> alter 'table_name', 'NORMALIZATION_ENABLED' => true
> normalizer_switch true
> normalizer_enabled
true
> enable 'table_name'

具体的なロジックを見てみましょう。


SimpleRegionNormalizer.java

...

int candidateIdx = 0;
while (candidateIdx < tableRegions.size()) {
HRegionInfo hri = tableRegions.get(candidateIdx);
long regionSize = getRegionSize(hri);
// if the region is > 2 times larger than average, we split it, split
// is more high priority normalization action than merge.
if (regionSize > 2 * avgRegionSize) {
LOG.info("Table " + table + ", large region " + hri.getRegionNameAsString() + " has size "
+ regionSize + ", more than twice avg size, splitting");
plans.add(new SplitNormalizationPlan(hri, null));
} else {
if (candidateIdx == tableRegions.size()-1) {
break;
}
HRegionInfo hri2 = tableRegions.get(candidateIdx+1);
long regionSize2 = getRegionSize(hri2);
if (regionSize + regionSize2 < avgRegionSize) {
LOG.info("Table " + table + ", small region size: " + regionSize
+ " plus its neighbor size: " + regionSize2
+ ", less than the avg size " + avgRegionSize + ", merging them");
plans.add(new MergeNormalizationPlan(hri, hri2));
candidateIdx++;
}
}
candidateIdx++;
}
...

たったこれだけです笑

SimpleRegionNormalizerは、テーブルのリージョンをひとつずつ、まずは平均サイズの2倍を越えるかどうか確認します。もし2倍以上であればスプリット対象とし、次のリージョンを精査します。そうでなければ次のリージョンと足したサイズが平均以下かどうか確認し、もし平均に満たなければ両リージョンをマージ対象として次の次のリージョンの精査に入ります。

このようにスプリットあるいはマージ対象のリージョンを集め、HMasterがひとつずつ実行するわけです。

なお、リージョンの合計サイズが1MBに満たない場合、スプリットもマージも発生しません。