データ モデルを単純化しすぎると、次のテーブルがあります。
CREATE TABLE storage (
id timeuuid,
foo blob,
bar blob,
baz blob,
data blob,
PRIMARY KEY ((id))
);
CREATE TABLE storage_idx_by_foo (
foo blob,
id timeuuid,
PRIMARY KEY ((foo), id)
);
CREATE TABLE storage_idx_by_bar (
bar blob,
id timeuuid,
PRIMARY KEY ((bar), id)
);
CREATE TABLE storage_idx_by_baz (
baz blob,
id timeuuid,
PRIMARY KEY ((baz), id)
);
最初のテーブルには数億のレコードを含めることができ、インデックス テーブルを使用して、クエリ可能なパラメーターに基づいてデータを簡単に検索します。
問題は、foo、bar、またはbazのいずれかに基づいてデータをパージする必要がある場合に発生します。ストレージテーブルとすべてのインデックス テーブルからエントリを削除する必要があります。したがって、たとえばfooで削除すると仮定すると、実行される手順は次のとおりです。
- 適切なインデックス テーブルに基づいて ID を見つけます (この場合はstorage_idx_by_foo ) 。
- barとbazを取得し、ストレージテーブルからレコードを削除します
- 残りの 2 つのインデックス テーブルからレコードを削除します ( bar / bazとidがあります) 。
ステップ 3 は、トゥームストーンが原因で問題になります。残りの 2 つのインデックス テーブルから何百万ものレコードを削除すると (つまり、パーティションによってではなく)、Cassandra は何百万ものトゥームストーンを作成し、圧縮が発生する前にデータを読み取るときに多くの頭痛の種となります。
簡単なブレインストーミングでは、次のことができることが示唆されています。
- パージ プロセス後に圧縮を強制する
- これらの 2 つのテーブルから削除せず、コード内の存在しないものを指すインデックス エントリを処理します
- ????
推奨されるアプローチは何ですか? 他の Cassandra ユーザーもこの問題に遭遇したと思いますが、「Cassandra のやり方が間違っている」以外のアドバイスをオンラインで見つけることができませんでした。この問題を回避するためにデータを別の方法でモデル化することはできなかったと思います (もし可能であれば、それについてのフィードバックもいただければ幸いです)。
現在、私たちはオプション 2 に傾いていますが、データベースにゴミが残るという考えは好きではありません。