HBaseでdelete後にputしたデータがscanやgetで取得できない件


仕事でぶち当たったので備忘録。
結論としてはHBaseにおける削除というものの概念を取り違えてただけという悲しい結果だったのですが、同じ轍を踏まないようにエントリに残しておきます。
バージョン機能使ってる場合は特に注意したほうがよさそうです。

何があったの?


以下のコマンドをHBase Shellで実行しました。

# (1) hogehogeテーブルのrowkey1で指定される行のcf:cqカラムのバージョン1000をvalue1で更新
put 'hogehoge', 'rowkey1', 'cf:cq', 'value1', 1000

# (2) 検索
scan 'hogehoge'

# (3) hogehogeテーブルのrowkey1で指定される行のcf:cqカラムのバージョン1000を削除
delete 'hogehoge', 'rowkey1', 'cf:cq', 1000

# (4) 検索
scan 'hogehoge'

# (5) 再度hogehogeテーブルのrowkey1で指定される行のcf:cqカラムのバージョン1000をvalue1で更新
put 'hogehoge', 'rowkey1', 'cf:cq', 'value1', 1000

# (6) 検索
scan 'hogehoge'

すると(6)での検索で、value1は検索できない(見つからない)のです。
(2)の検索では検索できるし、(3)で削除しているので(4)で検索できないのは当然なのですが、(5)で再度putしているのに(6)で検索できない!ナンデ?!という事態に遭遇したのです。

ナンデ?!


結論としては、HBaseの削除に関する"仕様"でした。

Delete は Put をマスクします。Delete が実行された後に行われた Put も例外ではありません。すでに説明したように、削除操作ではツームストーンが書き込まれ、書き込まれたツームストーンは次にメジャーコンパクションが実行された後に消去されます。たとえば、T 以下であるという条件を満たすあらゆるものを削除し、その後 T 以下のタイムスタンプで新たに Put を実行したとします。この場合、Put は削除操作の後に行われているにもかかわらず、この Put は削除ツームストーンによってマスクされます。

http://oss.infoscience.co.jp/hbase/book/versions.html


つまり、HBaseにおける削除とは

  • 特定バージョンではなく、特定バージョン以前のデータを全て削除するということ
  • バージョン指定が省略された場合は最新バージョンが指定されたとする
  • リアルタイムでデータ変更をしないという方針上、削除指示を出した時点では特定バージョン以前のデータをマスクするマーカを置くだけ
  • 実際の削除はメジャーコンパクション時に削除マーカに従って行われる
  • メジャーコンパクションによって削除マーカが削除されるまでは、削除対象バージョンへのPutは抑制される

ということらしいのです。


上記の例だと、(3)でバージョン1000を削除した時物理的なデータは削除されていなくて、実際にはバージョン1000を含むそれ以前のデータをマスクする削除マーカが置かれただけ。
なので(5)のputはクライアント側からは成功したように見えるのですが、実際には削除マーカによってブロックされていたわけです。
この削除マーカはメジャーコンパクション時に清算されるわけですが、逆に言えば、メジャーコンパクションまでは削除したバージョン以前のバージョンへの更新はできないわけです。
実際に(3)の後メジャーコンパクションを実行すれば、(5)のputは成功しました。

まとめ

  • HBaseにおける削除とは特定のバージョン(省略した場合は最新)を含むそれ以前のバージョン全てを削除するということ
  • deleteを発行したタイミングでは物理削除されずに削除マーカが置かれるだけ
  • 削除マーカは削除対象範囲のデータをマスクし、マスクされているデータへのputは音もなくブロックされる
  • メジャーコンパクションで削除マーカが清算されるまでは削除マーカがマスクする範囲へのputは出来ない


特定のバージョンではなく特定のバージョン以前のデータを全て削除するという仕様は、直感と異なるので注意が必要かなぁと思いました。
そもそもHBaseのバージョンの仕組みの使い道が未だによく分からない & HBase自体にいくつかバグがあるらしいので、あまり凝った使い方をしない方が安全なのかなぁと思ったりします。*1

2012-10-25 13:08 追記

HBaseのバージョンの仕組みについて幾つかバグがあるらしいと記載した件についてリプライ頂きました。現在は修正されているそうです。

参考ページ

*1:あるいはバージョン機能自体を使わずにVERSIONS = 1運用で設計するか