2016-10-10 8 views
0

私のテーブルの完全なパーティションを照会したい。 私の複合パーティションキーは(id, date, hour_of_timestamp)で構成されています。 iddateは文字列、hour_of_timestampは整数です。Cassandra - パーティション全体を照会するINクエリまたはTOKENクエリ?

データを取り込み中にホットスポットが原因で、hour_of_timestampフィールドを自分のパーティションキーに追加する必要がありました。

今、データの完全なパーティションを照会する最も効率的な方法は何ですか? this blogによれば、SELECT * from mytable WHERE id = 'x' AND date = '10-10-2016' AND hour_of_timestamp IN (0,1,...23);を使用すると、コーディネーター・ノードに多くのオーバーヘッドが生じています。

TOKEN関数を使用し、2つのトークンを使用してパーティションをクエリする方がよいですか?このようなSELECT * from mytable WHERE TOKEN(id,date,hour_of_timestamp) >= TOKEN('x','10-10-2016',0) AND TOKEN(id,date,hour_of_timestamp) <= TOKEN('x','10-10-2016',23);

ように、私の質問は: は、私は私のデータのパーティション全体を照会するためINまたはTOKENクエリを使用する必要がありますか?または、私はhour_of_timestampの値ごとに1つずつ23個のクエリを使用し、残りの作業をドライバに任せますか?

私はCassandra 3.0.8と最新のDatastax Java Driverを使用して6ノードクラスタに接続しています。

+0

PRIMARY KEY定義全体を投稿できますか? – Aaron

+0

@Aaron PRIMARY KEY((log_creator、date、hour)、ts、log_id)が実際の定義です。質問のフィールド名をより一般的なものに調整しました... 'ts'は' timestamp'型で、 'log_id'は別の文字列です。 – j9dy

答えて

1

あなたは言う:

は今、私は私のデータの完全な パーティションを照会するための最も効率的な方法は何思ったんだけど?このブログによると、SELECT *を mytableからどこで使用するのですか?id = 'x' AND date = '10 -10-2016 'AND hour_of_timestamp IN(0,1、... 23);コーディネーター・ノードに多くのオーバーヘッドを引き起こしています。

実際には24個のパーティションをクエリします。

データの取り込み中にホットスポットを避けるために時間を追加するため、1つのパーティションが24個のパーティションで構成されているという設計があったことでしょう。

  1. ファイル名を指定して実行時には1つのクエリ:両方のモデル(ホットスポットと古いものと新しいもの)のデータにはまだタイムスタンプによって順序付けられていることに注目し、次の2つの選択肢があります。
  2. 最初に2回のクエリを実行し、次に1回のクエリで結果を「プリフェッチ」します。
  3. 24個のクエリを並行して実行します。

CASE 1

あなたはデータを順次処理する場合は、最初の選択肢は、時間0のクエリを実行することです、プロセスデータと、終了したら、その1時間のためのクエリを実行し、 on ...これは簡単な実装であり、これ以上の価値はないと私は考えています。

CASE 2

クエリがデータ処理よりも時間がかかる場合は、「プリフェッチ」いくつかのデータをできました。したがって、初めて2つのクエリを並列に実行して、時間0と1の両方のデータを取得し、時間0のデータの処理を開始することができました。その間、時間1のデータが到着するので、時間0のデータを処理するのを完了すると、時間2のデータをプリフェッチして1時間のデータの処理を開始できます。このようにして、データを高速化できます処理。もちろん、タイミング(データ処理とクエリ時間)によっては、「プリフェッチ」クエリの数を最適化する必要があります。

Javaドライバーは自動的にページ番号を設定します。検索されたパーティションのサイズに応じて、データ処理をブロックしないようにその機能を無効にしたり、何かで先読みしたいthisのように:あなたはチューンrs.getAvailableWithoutFetching() == 100は、より良いあなたのプリフェッチ要件に合わせてできること

ResultSet rs = session.execute("your query"); 
for (Row row : rs) { 
    if (rs.getAvailableWithoutFetching() == 100 && !rs.isFullyFetched()) 
     rs.fetchMoreResults(); // this is asynchronous 
    // Process the row ... 
} 

最初に複数のパーティションをプリフェッチすることもできます。これにより、処理がデータ取得部分を待つことがなくなります。あなたはたとえば、あなたが時間の3と6の両方のデータを必要とし、一緒に別のパーティションからのデータを処理する必要がある場合は、あなたが「依存」して、グループのデータに試みることができる

CASE 3

(例えば、両方の時間を問い合わせます3と6は並行している)。

これらのすべてが必要な場合は、24個のクエリを並列に実行し、アプリケーションレベルでそれらを結合する必要があります(なぜ、複数パーティションのINを避けるべきかはすでに分かっています)。あなたのデータはであり、すでにになっているので、アプリケーションレベルの努力は非常に小さいでしょう。

関連する問題