2014-04-27

Cassandra を使ったデータ削除の実装でコレをやるとマズイ

最近はお仕事で Cassandra をメインのデータストアにしたサービスを開発しています。
KVSなデータストアでの開発にもだいぶ慣れてきたところなんですが、落とし穴があったのでメモφ(`д´)

データ削除時に tombstone (墓石) を建てる


Cassandra はレコードの削除を行うときに、tombstone という削除フラグ的なものを立てて論理削除ぽいことをしているらしい。
なので tombstone だけでは物理的にレコードは消えておらず、Java の GC とか minor compaction をされるまで残り続けるみたいです。

検索するときの邪魔になる

Cassandra はデータ検索時に tombstone があるとそれをスキップして走査するという動きになっているらしい。
なので、大量の tombstone があると検索効率が落ちていきます。
データ削除を大量のレコードに対してやるとこうなっちゃうんですね。
cassandra/system.logとかには

Read 0 live and xxxx tombstoned cells

とか表示されているはず。

回避策1

データ走査対象にならないように、適切にレコードに対して key を割り振りましょう。
単純に1種類の ID とかで走査してしまうような検索を避けるために、もう1種類グループ分けできるような ID を振り分けると検索対象から外れて tombstone を踏むことが減ります。

回避策2

gc_grace_seconds の時間を短くして GC される間隔を短くする。
デフォルトだと10日くらいなので、それを短くするとか。これはパフォーマンスと相談して時間を決めるのが良いかと。
CQLで

> UPDATE COLUMN FAMILY [CF名] with GC_GRACE = [時間];

とか書けばいいらしい。

まとめ

一時的にデータを作って、一気に消すような実装が入ってるときに気にしたい tips でした。
tombstone 、墓石と名付けるセンスが面白いですね( ・`v・´)

2 件のコメント:

Katsutoshi Nagaoka さんのコメント...

> gc_grace_seconds
パフォーマンスもそうだけど、削除済みデータの復活を防ぐために repair 間隔も考慮しなきゃいけないとおもった

紫竹佑騎 さんのコメント...

その通りですね。repairも調整しないとダメでした。ご指摘ありがとうございます!