3

ebay の技術ブログdatastax 開発者のブログの指針に従って、Cassandra 1.2 でいくつかのイベント ログ データをモデル化します。パーティション キーとして、「ddmmyyhh|bucket」を使用します。ここで、bucket は 0 からクラスター内のノード数までの任意の数です。

データモデル

cqlsh:Log> CREATE TABLE transactions (yymmddhh varchar, bucket int, rId int, created timeuuid, data map, PRIMARY KEY((yymmddhh, bucket), created) );

(rId は、イベントを発生させたリソースを識別します。) (マップは、JSON から派生したキーと値のペアです。キーは変更されますが、それほど多くはありません)

これは、1 時間あたり X バケットの複合プライマリ/行キーに変換されると思います。私の列名は timeuuids よりも優れています。このデータ モデルのクエリは期待どおりに機能します (時間範囲をクエリできます)。

問題はパフォーマンスです。新しい行を挿入する時間が継続的に増加します。だから私はs.thをやっています。間違っていますが、問題を特定できません。

行キーの一部として timeuuid を使用すると、パフォーマンスは高いレベルで安定したままになりますが、クエリを実行できなくなります (もちろん、行キーを使用しないクエリでは、「フィルタリング」に関するエラー メッセージがスローされます)。

何か助けはありますか?ありがとう!

アップデート

マップ データ型から定義済みの列名に切り替えると、問題が軽減されます。挿入時間は、挿入ごとに約 <0.005 秒にとどまっているようです。

「マップ」データ型の効率的な使用方法は? そして、キーのわずかな違いだけで何千もの挿入を効率的に行うにはどうすればよいでしょうか。

マップにデータを使用するキーは、ほとんど同じままです。各キーが追加の列を作成するか、「マップ」ごとに1つの新しい列を作成するか? それは... 私には信じがたいことです。

4

2 に答える 2

2

行を少し異なる方法でモデル化することをお勧めします。コレクション内の要素が多すぎる可能性がある場合、コレクションを使用するのはあまり適していません。その理由は、2 バイトを使用してコレクション内の要素の数を表す Cassandra バイナリ プロトコルの制限です。これは、コレクションに 2^16 を超える要素が含まれている場合、サイズ フィールドがオーバーフローし、サーバーがすべての要素をクライアントに送り返しても、クライアントにはN % 2^16最初の要素しか表示されないことを意味します (したがって、2^16 がある場合+ 3 つの要素がある場合、クライアントには要素が 3 つしかないかのように見えます)。

コレクションにそれほど多くの要素を入れるリスクがない場合は、このアドバイスを無視してかまいません。コレクションを使用するとパフォーマンスが低下するとは思いませんが、それがどのように起こるかはよくわかりません。

CQL3 コレクションは、基本的にはストレージ モデルの単なるハックです (否定的な意味でのハックを意味するものではありません)。上記の制限によって制約されない MAP のような行を自分で作成できます。

CREATE TABLE transactions (
  yymmddhh VARCHAR,
  bucket INT,
  created TIMEUUID,
  rId INT,
  key VARCHAR,
  value VARCHAR,
  PRIMARY KEY ((yymmddhh, bucket), created, rId, key)
)

(マップキーを主キーに移動したことに注意してください。何がrId何であるかはわかりませんrIdが、これは正しいと思います)

これには、MAP の使用に比べて 2 つの欠点があります。データを照会するときにマップを再構築する必要があり (マップ エントリごとに 1 行が返されます)、C* がいくつかの余分な列を挿入するため、少し多くのスペースを使用します。ただし、大きなコレクションを取得しても問題がないという利点があります。

最終的には、データのクエリ方法に大きく依存します。挿入を最適化するのではなく、読み取りを最適化します。たとえば、マップ全体を毎回読み取る必要はなく、通常は 1 つまたは 2 つのキーを読み取るだけの場合は、代わりにパーティション/行キーにキーを配置し、キーごとに個別のパーティション/行を作成します (このは、キーのセットが固定されていると想定しているため、何を照会するかがわかります。そのため、前述したように、データを照会する方法に大きく依存します)。

また、コメントで、バケットの数を 3 (0-2) から 300 (0-299) に増やすとパフォーマンスが向上したと述べました。これは、負荷をクラスタ全体に均等に分散させるためです。のように、時間に基づくパーティション/行キーがあるyymmddhh場合、すべての書き込みが行われるホット パーティションが常に存在します (1 日を通して移動しますが、任意の時点で 1 つのノードのみにヒットします)。列/セルに平滑化係数を正しく追加しましたbucketが、値が 3 つしかないため、少なくとも 2 つが同じ物理ノードに到達する可能性が高すぎます。300 を使用すると、はるかに優れたスプレッドが得られます。

于 2013-06-15T11:39:16.977 に答える
0

yymmddhh を行キーとして使用し、bucket+timeUUID を列名として使用します。各バケットには 20 個のレコードがあるか、レコード数が固定されていません。バケットはカウンター クローン ファミリーを使用して管理できます。

于 2013-06-13T10:38:58.460 に答える