0

次のスキーマを持つ cassandra に CF があるとします。

  • タイムスタンプ
  • デバイスID
  • 装置名
  • デバイス所有者

PKEY (タイムスタンプ、デバイス ID): これは、パーティションがタイムスタンプで発生していることを意味します。

以下は、私が興味を持っているクエリです。

Select * from schema where TimeStamp='..' Select * from schema where DeviceID='..'

最初のクエリは 500K のレコードを返し、2 番目のクエリは 50K のレコードを返します。最初のクエリは、単一ノードでのすべてのフェッチがボトルネックであるため、TimeStamp 用に複数のノードにデータを分散したいと考えています。2 番目のクエリのボトルネックは、すべてのレコードが異なるノードのディスク全体に分散され、複数のディスク フェッチが発生する可能性があることです。

ここで、特定の TimeStamp のエントリもクラスター ノード全体に分散されるように、仮想パーティションを作成するとします。これは PlayORM で可能ですか? はいの場合、そうできるコード(またはそのようなことをする例)を提供していただけますか?

もう 1 つの要件は、特定のデバイス ID のすべてのレコードを検索することです。同じ CF の「デバイス ID」で仮想パーティショニングを行うことはできますか? はいの場合、その方法を示すコード/リンクを提供していただけますか?

このようなことを行うためのソース コードを誰かが提供してくれるとうれしいです。なぜなら、ドキュメンテーションは理解するのがそれほど簡単ではなく、現在のドキュメンテーションを読むだけでコードを書くことは悪夢であることが判明しているからです。「完全な」コード例がなければ、PlayORM を評価することは不可能に思えます。

4

1 に答える 1

3

はい、PlayOrm でこのようなものが必要になります... (何か不足している場合はコメントを投稿してください。また返信できます)。

https://github.com/deanhiller/playorm/blob/master/src/test/java/com/alvazan/test/db/PartitionedTrade.java

また、クエリ PARTITIONS t('account', :partId) SELECT t FROM TABLE as t INNER JOIN t.security as s WHERE s.securityType = :type and t.numShares = :shares"

「account」はパーティション列を識別し、:partId はパーティションの ID です。あなたの場合、PARTITIONS t('deviceid', {actualDeviceId}) または t('time', {time}) があり、最初のパラメーターは列名で、2 番目のパラメーターは時間のパーティションの実際の ID またはデバイスのパーティションの ID。X がおそらく約 300 万である X 百万を超える行をパーティションに含めないでください。

パッケージ com.alvazan.test.db にはさまざまな例があり、com.alvazan.test はそれらの使用方法を示しています。あなたのフィードバックに基づいてドキュメントを微調整し、コードベースのコードへのリンクを直接配置するよう誰かに依頼する予定です......

ps。github からダウンロードし、gradlew eclipse または gradle eclipse (OS に応じて) を実行してから eclipse にインポートすると、すべてのテストがメモリ内の noSQL バージョンですぐに機能します (開発に使用します)。次に、cassandra に対して実行する場合は、ドキュメントに 1 行を変更する方法があり、すべてのテストが cassandra に対して実行されます。

スピードアップ。PlayOrm は、各パーティション (パーティションごとのインデックス) に対して複合名パターンを使用してワイド行を実行します。クエリを実行すると、この行が 200 (または指定したサイズ) のバッチで読み取られ、インデックスで見つかったキーを使用してすべてのマシンに要求が送信されます (つまり、この時点で並列スループットが得られます)。これは、すべてのパーティションがクラスター全体に分散されているためです。実際、すべてのノードは、所有するノードの数とパーティションの数に応じて、ほぼすべてのパーティションのスライスになります (つまり、100 ノードと 32 パーティション。すべてのノードにすべてのパーティションがあるわけではありません)。

内部では、playorm は非常に単純なことを行っています。すべての行は、まったく分割されていないかのように書き込まれます!!! 次に、インデックス行が書き込まれ (RF=3 は 3 つのノードを意味します)、インデックス行の名前は /TABLE/partition/column/partitionId です。それがインデックスの行キーです。コマンド ライン ツールを使用すると、自分でインデックスを読み取ったり、インデックスだけを読み取ったり、パーティションにクエリを実行したりすることもできます。これには、playOrm のコマンド ライン ツールを使用します。

最後に、cassandra の幅の広い行は順序付けられるため、PARTITIONS d('deviceid', 'device1') select d from TABLE as d where d.time > Integer.MIN_INT のような特定のインデックスを使用する場合

その後、結果はそのインデックスの順序で返されます(つまり、この場合は時間)。逆の順序が必要な場合は、cursor.afterLast、次にcursor.previous、cursor.previousなどを呼び出します。

明確にするために、PlayOrm はここで cassandra のパーティショニングを意図的に無視しています。パーティションがまったくないようにデータを書き込みます。また、インデックスを 1 つまたは 2 つ書き込みます。時間ごとに 1 回、デバイス ID ごとに 1 回、合計 2 回パーティション分割するとします。この場合、行キーを使用して StringIndice または IntegerIndice テーブル (BigInteger!!! Integer ではない) に書き込みます (エンティティは Devices と呼ばれます)。また、エンティティで、「名前」列に @NoSqlIndexed があるとしましょう!!!!

/Devices/byDevice/device1/name = the wide row
/Devices/byTime/time56/name = the wide row

@NoSqlIndexed 列が多い場合は、インデックス テーブルにさらに行があります。ただし、すべての行はクラスター全体に分散されており、パーティショニングは考慮されません。

これは理にかなっていますか?気軽に試してみてください。実装に関する問題や質問がある場合は、stackoverflow に新しい質問を投稿してください。

于 2013-03-21T15:27:26.593 に答える