パーティション キーのカーディナリティと追加のストレージ要件の他に、多数のクラスター列のアプローチを使用した場合、何に注意する必要がありますか?
これは興味深い問題のように思えたので、異なる PRIMARY KEY 構造とオプションの CQL テーブルをいくつか作成しました。次に、 http: //geohash.org/を使用していくつかのエンドポイントを作成し、それらを挿入しました。
aploetz@cqlsh:stackoverflow> SELECT g1, g2, g3, g4, g5, g6, g7, g8, geohash, pid, data FROm georecords3;
g1 | g2 | g3 | g4 | g5 | g6 | g7 | g8 | geohash | pid | data
----+----+----+----+----+----+----+----+--------------+------+---------------
d | p | 8 | 9 | v | c | n | e | dp89vcnem4n | 1001 | Beloit, WI
d | p | 8 | c | p | w | g | v | dp8cpwgv3 | 1003 | Harvard, IL
d | p | c | 8 | g | e | k | t | dpc8gektg8w7 | 1002 | Sheboygan, WI
9 | x | j | 6 | 5 | j | 5 | 1 | 9xj65j518 | 1004 | Denver, CO
(4 rows)
ご存じのとおり、Cassandra は、特定の正確なキーでデータを返すように設計されています。複数のクラスタリング列を使用すると、Cassandra が取得したいデータをすばやく特定できるようになるという点で、そのアプローチに役立ちます。
変更について私が考える唯一のことは、PRIMARY KEY なしで、geohash
またはpid
PRIMARY KEY でできるかどうかを確認することです。pid
私の腸は、実際にはクエリを実行するものではないため、を取り除くように言っています。それが提供する唯一の価値は、同じジオハッシュを複数回保存することを計画している場合に必要になる一意性です。
PRIMARY KEY に含めると、キー以外の列が 1 つ残り、ディレクティブpid
を使用できるようになります。WITH COMPACT STORAGE
実際にあなたを得る唯一の真の利点は、クラスタリング列名が値とともに保存されないため、ディスク領域を節約することです。cassandra-cli
これは、ツール内からテーブルを見ると明らかになります。
コンパクト収納なし:
[default@stackoverflow] list georecords3;
Using default limit of 100
Using default cell limit of 100
-------------------
RowKey: d
=> (name=p:8:9:v:c:n:e:dp89vcnem4n:1001:, value=, timestamp=1428766191314431)
=> (name=p:8:9:v:c:n:e:dp89vcnem4n:1001:data, value=42656c6f69742c205749, timestamp=1428766191314431)
=> (name=p:8:c:p:w:g:v:dp8cpwgv3:1003:, value=, timestamp=1428766191382903)
=> (name=p:8:c:p:w:g:v:dp8cpwgv3:1003:data, value=486172766172642c20494c, timestamp=1428766191382903)
=> (name=p:c:8:g:e:k:t:dpc8gektg8w7:1002:, value=, timestamp=1428766191276179)
=> (name=p:c:8:g:e:k:t:dpc8gektg8w7:1002:data, value=536865626f7967616e2c205749, timestamp=1428766191276179)
-------------------
RowKey: 9
=> (name=x:j:6:5:j:5:1:9xj65j518:1004:, value=, timestamp=1428766191424701)
=> (name=x:j:6:5:j:5:1:9xj65j518:1004:data, value=44656e7665722c20434f, timestamp=1428766191424701)
2 Rows Returned.
Elapsed time: 217 msec(s).
コンパクトな収納:
[default@stackoverflow] list georecords2;
Using default limit of 100
Using default cell limit of 100
-------------------
RowKey: d
=> (name=p:8:9:v:c:n:e:dp89vcnem4n:1001, value=Beloit, WI, timestamp=1428765102994932)
=> (name=p:8:c:p:w:g:v:dp8cpwgv3:1003, value=Harvard, IL, timestamp=1428765717512832)
=> (name=p:c:8:g:e:k:t:dpc8gektg8w7:1002, value=Sheboygan, WI, timestamp=1428765102919171)
-------------------
RowKey: 9
=> (name=x:j:6:5:j:5:1:9xj65j518:1004, value=Denver, CO, timestamp=1428766022126266)
2 Rows Returned.
Elapsed time: 39 msec(s).
ただし、次の理由から使用しないことをお勧めします。WITH COMPACT STORAGE
- テーブルの作成後に列を追加または削除することはできません。
- テーブルに複数の非キー列が含まれないようにします。
- これは、列ファミリー (テーブル) モデリングに対する古い (非推奨の) 倹約ベースのアプローチで使用することを実際に意図しており、実際には使用/不要になりました。
- はい、ディスク容量を節約できますが、ディスク容量は安価なので、これは非常に小さな利点だと思います。
「パーティションキーのカーディナリティ以外」と言ったのは知っていますが、とにかくここで言及します。d
サンプル データ セットを見ると、ほぼすべての行がパーティション キーの値と共に格納されていることがわかります。ウィスコンシン州/イリノイ州のステートライン エリアで geohash を追跡するこのようなアプリケーションを自分で作成するとしたら、ほとんどのデータが同じパーティションに格納される (クラスター内にホットスポットを作成する) という問題が発生することは間違いありません。したがって、ユース ケースと潜在的なデータを知っていれば、おそらく最初の 3 つほどの列を 1 つのパーティション キーに結合します。
すべてを同じパーティション キーに格納する場合のもう 1 つの問題は、各パーティションに最大で約 20 億列を格納できることです。したがって、データがそのマークを超える可能性があるかどうかにかかわらず、いくつかのことを後回しにすることも理にかなっています. そして明らかに、パーティション キーのカーディナリティが高いほど、この問題に遭遇する可能性は低くなります。
あなたの質問を見ると、あなたは自分のデータを見て、この...明確な「プラス」を理解しているように見えます。また、パーティション キーに 30 個の一意の値があれば、十分な分散が提供されます。私は、それがどれほど大きな取引になるかを説明するのに少し時間を費やしたかっただけです.
とにかく、あなたが正しい軌道に乗っているように聞こえるので、「うまくやった」ことも追加したかった.
編集
私にとってまだ解決されていない問題は、どのアプローチがどのような状況でより適切にスケーリングするかということです。
スケーラビリティは、N ノードにまたがる R レプリカの数にさらに関係しています。Cassandra は直線的にスケーリングします。追加するノードが多いほど、アプリケーションが処理できるトランザクションが増えます。純粋にデータ分散のシナリオから、最初のモデルのパーティション キーのカーディナリティが高くなるため、2 番目のモデルよりもはるかに均等に分散されます。ただし、最初のモデルは、クエリの柔軟性に関して、より制限的なモデルを提示します。
さらに、パーティション内で範囲クエリを実行している場合 (そう言ったと思います)、2 番目のモデルは非常にパフォーマンスの高い方法でそれを可能にします。パーティション内のすべてのデータは同じノードに格納されます。そのため、...etc...に対して複数の結果をクエリするg1='d' AND g2='p'
と、非常にうまく機能します。
もっとデータをいじってテストケースを実行する必要があるかもしれません。
それはいい考えです。2 番目のモデルが最適な方法であることがわかると思います (クエリの柔軟性と複数行のクエリの観点から)。単一行のクエリに関して、2 つの間にパフォーマンスの違いがある場合、私の疑いでは、それは無視できるはずです。