HBaseのクラウド対応について

この記事では、今年の9月に行われた[db tech showcase tokyo 2019](https://www.db-tech-showcase.com/dbts/tokyo)で、私が[発表した内容](https://www.db-tech-showcase.com/wp-content/uploads/2019/10/20191031up_day3_dl3_dbts.pdf)の一部である「HBase on Cloud」について紹介します。

# 背景

近年のクラウド環境の普及により、HBaseをクラウド上で動かしたという要件が出てきています。当然、これまでオンプレ環境でやってきたように、Aamzon EC2やGCE(Google Compute Engine)などのIaaS上にそのままHBase、HDFS等をインストールして使うこともできますが、それだと金銭的なコストの面で最適とは言えません。そこで、どうやってHBaseをクラウド上で最適に動かしていくかについてHBaseコミュニティがどのようにアプローチしているかについて紹介したいと思います。

# HBaseのファイルI/O

まず、HBaseのファイルI/Oについて説明します。

HBaseでは、主にデータファイルであるStoreFileとWAL(Write Ahead Log)の2種類のファイルがあり、これまでは通常これらをHDFSに書き込んでいました。簡単にHBaseの書き込みの手順を説明すると以下のようになります。

まず、クライアントがデータをPutすると、そのデータはRegionServer側のメモリ上にあるMemStoreと呼ばれる領域に書き込まれます。それと同時にWALと呼ばれるストレージ上のログファイルにデータを追記します。そして、MemStoreがある一定の大きさになるとストレージ上にStoreFileとして書き込まれます(Flush)。さらに、StoreFileの数が多くなると、それらのStoreFileをマージし数を減らすCompactionという処理が行われます。

WALファイルは、RegionServerがダウンした場合にMemStoreが失われてしまうので、その復旧のために使われます。また、CompactionはStoreFileの数が増えすぎると読み込みの効率が下がってしまうのでそれを防ぐために行われます。

このような、アーキテクチャをLog Structured Merge tree(あるいはLSM tree)と呼びます。

# HBaseをクラウドで動かすためのチャレンジ

HBaseをクラウド上で動かしていくために、重要なポイントとなるのはこれらのファイルをどうするかということになります。これまでオンプレ環境でやってきたように、Aamzon EC2やGCE(Google Compute Engine)などのIaaS上にそのままHBase、HDFS等をインストールして使うこともできます。

ただし、Amazon S3やGCS(Google Cloud Storage)などのオブジェクトストアを使った方がコストを安くすることができますし、コンピューティングノードとストレージを分離することができるので、必要ないときはコンピューティングノードを停止し、必要なときだけ立ち上げることができ、更にコストを下げることができます。

では、先ほど説明したStoreFileとWALをそのままS3やGCSなどのオブジェクトストアを書き込めばよいかというとそうはうまくはいきません。

# オブジェクトストアの整合性の問題

StoreFileとWALはそれぞれ特徴が違います。

StoreFileは、一度書き込まれたら変更されることがなく(イミュータブル)で、キャッシュすることが容易です。ただし、StoreFileに関するオペレーションとして、FlushやCompactionの際に、追加されたりリネーム(移動)されたりするのと、StoreFileが入っているディレクトリ自体をリネームすることもあります。これらのオペレーションはアトミックに行われる必要があります。

WALは、前述したようにMemStoreのリカバリのために使われるので、MemStoreがFlushされストレージに永続化されると、その分のWALは不必要になり削除されます。そのため、比較的Short-livedなものになります。ただし、RegionServerがダウンした際に、すぐにMemStoreを復旧しなければならないので、WALの書かれたデータはすぐに読み込めるようになっていなければなりません(Sub-second durability requirements)。

クラウドで提供されているオブジェクトストアは多くは、結果整合性という整合性モデルを採用しており、上記の要件、特にWALの要件に対応できません。StoreFileに関してもそのままでは使えず、工夫して使う必要があります。

ここからは、StoreFileとWALそれぞれでHBaseではどんなアプローチをしているかを説明します。

# StoreFileへのアプローチ

まずは、 StoreFileへのアプローチから説明します。ここでは、Amazon S3にフォーカスした話になります。現状、HBaseコミュニティではS3についてのみテストしているからです。理論的には、GCS等の他のオブジェクトストアでも動作可能です。

S3の整合性モデルは結果整合性を採用しており、そのままではStoreFileを保存するために使用できません。具体的には、ディレクトリ内のオブジェクトのリスティング時やオブジェクトのステータスの取得時などで常に正しい状態が見えるとは限りません。HBaseはストレージに対するオペレーションはアトミックに実行されることが想定されているので、そのままではデータロスしてしまう可能性があります。

S3の整合性モデルについての詳細は以下の資料をご覧ください。

「Hadoop/Spark で Amazon S3 を徹底的に使いこなすワザ」
https://www.slideshare.net/ssuserca76a5/hcj2019-hadoop-sparks3#25

この問題を軽減するための既存のソリューションとして、[S3Guard](https://hadoop.apache.org/docs/current/hadoop-aws/tools/hadoop-aws/s3guard.html)があります。S3Guardを使うことによって、ディレクトリ内のオブジェクトのリスティング時やオブジェクトのステータスの取得時などで常に正しい状態が見えることが保証されます。ただし、S3Guardだけではディレクトリのリネーム時などすべての場合をカバーできておらず、さらなるソリューションが必要となりました。そこでHBaseのサブプロジェクトしてHBOSS(HBase Object Store Semantics)が立ち上がりました。

## HBOSS

[HBOSS](https://github.com/apache/hbase-filesystem/tree/master/hbase-oss)は、StoreFileの保存で必要な整合性と、S3Guardでできないことのギャップを埋めるためのソリューションです。Hadoop Filesystem APIを実装していて、オブジェクトストアに分散ロック機構を追加し、オブジェクトストアに対するオペレーションがアトミックに実行されることを保証します。S3Guardで保証できなかったディレクトリのリネームもアトミックに実行することができます。HBOSSはロックの実装がいくつかありますが、本番用に想定されているものとしてはZookeeperを使った実装があります。HBaseは既にZookeeperを使用しているので、追加でコンポーネントをインストールする必要はありません。

このように、Amazon S3を使う場合には、S3Guard + HBOSSを使うことによってStoreFileを保存することができます。

##課題

現状の課題としては、HDFSに比べてS3にアクセス時のレイテンシが高いことがあげられます。S3のレイテンシは数十ミリ秒から数百ミリ秒に対して、HDFSのレイテンシは数ミリ秒以下となりますので、レイテンシが重要なアプリケーションに対しては大きなインパクトになり得ます。ただし、HBaseにはBlockCache/BucketCacheというキャッシュ機構があるので、これで軽減することが可能です。

また、現時点ではディレクトリのRenameの失敗時に不整合な状態になってしまう問題は解決できていないという課題もあります。

# WALへのアプローチ

次に、WALへのアプローチについて説明します。

WALに関しては、前述したように、強い整合性が必要となってくるので、Amazon S3のような強い整合性モデルを持たないオブジェクトストアに保存することは難しいです。そのため、従来どおりHDFSを使うか、独自にWALを管理する必要があります。独自にWALを管理するアプローチとしてRatis LogService backed WALsがあります。

## Ratis LogService backed WALs

[Ratis LogService backed WALs](https://issues.apache.org/jira/browse/HBASE-20951)は、[Apache Ratis](http://ratis.incubator.apache.org/)というRaftコンセンサスプロトコルのJava実装ライブラリを使用してWALのレプリケーションを管理するというアプローチです。これ自体はまだ未完成で、最初のステップとしてWAL周りのリファクタリングが行われています。現状、HDFSを使うことが前提の作りになっているので、そこに抽象化レイヤを入れようとしています。このリファクタリングが完了すれば、Ratisだけではなく、WALに他の実装(例えばKafkaやAmazon Kinesis等)を使うことも容易になります。

# まとめ

今回は、HBaseのクラウド対応について紹介しました。ちなみに、下記の記事に書いてあるとおり、CDP Public CloudでOperational Database (HBase)をAWSで立ち上げた場合には、StoreFileはS3(+ S3Guard + HBOSS)を使い、WALに関しては従来どおりHDFSを使います。

「How HBase in CDP Can Leverage Amazon’s S3」
https://blog.cloudera.com/how-hbase-in-cdp-can-leverage-amazons-s3/

![CDP](https://ndu0e1pobsf1dobtvj5nls3q-wpengine.netdna-ssl.com/wp-content/uploads/2019/09/Screen-Shot-2019-09-26-at-8.53.03-AM.png)