3

Cassandra 2.1.3 で時系列アプリケーションのデータモデルを作成しています。システムのユーザーごとに X 量のデータを保存する予定ですが、この要件に合わせて設計するための最良のアプローチは何か疑問に思っています。

オプション1:

パーティション キーで「バケット」を使用して、X 期間のデータが同じ行に入るようにします。このようなもの:

((id, bucket), timestamp) -> data

このバケットの概念を維持することを犠牲にして、一度に 1 つの行を削除できます。また、クエリできる範囲も制限さtimestampれるため、複数のクエリが発生する可能性があります。

オプション 2:

すべてのデータを同じ行に格納します。N 個の削除は列ごとです。

(id, timestamp) -> data

範囲クエリも簡単です。しかし、多くの列を削除した後のパフォーマンスはどうでしょうか?

TTL を使用してデータを期限切れにすることを計画している場合、2 つのモデルのどちらが最高のパフォーマンスを発揮しますか? Option1 << Option2 の墓石のオーバーヘッドですか、それとも両方のモデルで列ごとに墓石がありますか?

墓石墓地に埋葬されるのを避けようとしている。

4

2 に答える 2

3

それはすべて、最終的に選択する特定のパーティションキーに対してどれだけのデータを計画しているか、TTL が何であるか、および作成しているクエリに依存すると思います。

特にTTLがすべての書き込みで同じである場合、私は通常、オプション#1に傾倒します。さらに、LeveledCompactionStrategy または DataTieredCompactionStrategy を使用している場合、Cassandra は同じパーティションのデータを同じ SSTable に保持することで、読み取りパフォーマンスを大幅に向上させます。

オプション #2 を使用すると、同じパーティションのデータが複数のレベル (LCS を使用している場合) または一般的には複数の sstable に分散する可能性があり、クエリの性質によっては、多くの SSTable から読み取る必要があります。 . 非常に広いパーティションがある場合、特定の cassandra ノードを過負荷にする可能性がある、ホットスポッティングの問題もあります。

#1(あなたがほのめかしている)のもう1つの利点は、パーティション全体を簡単に削除できることです。これにより、はるかに安価な単一の廃棄マーカーが作成されます。また、同じ TTL を使用している場合、そのパーティション内のデータはほぼ同時に期限切れになります。

複数のクエリを作成して複数のパーティションを読み取らなければならないのは、アプリケーションの処理が複雑になるため、少し面倒だという点には同意します。暗黙的に決定できない場合は、指定された ID のバケットを追跡するために別のテーブルを維持する必要がある場合もあります。

パフォーマンスに関する限り、アプリケーションがクエリを作成するときにクロス パーティションを読み取る必要があると思いますか? たとえば、「最新の 1000 レコード」に対するクエリがあり、パーティションが通常それよりも広い場合、オプション #1 に対して 1 つのクエリを作成するだけでよい場合があります。ただし、「give me all records」のようなクエリが必要な場合は、バケットごとにクエリを作成する必要があるため、オプション #2 の方が適している可能性があります。

于 2015-03-16T16:20:34.727 に答える
2

上記で説明したテーブルを作成したら、次のようにします。

CREATE TABLE option1 (
                 ...   id bigint,
                 ...   bucket bigint,
                 ...   timestamp timestamp,
                 ...   data text,
                 ...   PRIMARY KEY ((id, bucket), timestamp)
                 ... ) WITH default_time_to_live=10;

CREATE TABLE option2 (
                 ...   id bigint,
                 ...   timestamp timestamp,
                 ...   data text,
                 ...   PRIMARY KEY (id, timestamp)  
                 ... ) WITH default_time_to_live=10;

テスト行を挿入しました:

INSERT INTO option1 (id,bucket,timestamp,data) VALUES (1,2015,'2015-03-16 11:24:00-0500','test1');
INSERT INTO option2 (id,timestamp,data) VALUES (1,'2015-03-16 11:24:00-0500','test2');

... 10 秒間待機し、トレースをオンにしてクエリを実行したところ、各テーブルの廃棄数が同じであることがわかりました。いずれにせよ、それはあなたにとってあまり心配するべきではありません。

本当の問題は、パーティションあたり 20 億列の制限に達すると思われる場合は、オプション 1 が安全な方法であるということです。大量のデータがある場合は、オプション #1 のパフォーマンスが向上する可能性があります ( bucket.

tl;dr;

どちらのオプションを選択してもパフォーマンスとトゥームストーンの問題は似ているため、クエリが簡単なという理由だけで、オプション #2 の方が優れていると思います。

于 2015-03-16T17:11:26.867 に答える