0

Cassandra に列ファミリーがあり、このようなものを保存します。

BundleName    |     Version
----------------------------
FrameworkBundle    1.0.0
BundleA            1.0.0
BundleB            1.0.0
BundleC            1.0.0
BundleD            1.0.0

Astyanax クライアントを使用して、Cassandra データベースからデータを取得しています。Cassandra からデータを取得するメソッドを用意します。

public Map<String, String> getFromDatabase() {

    // 1) For the first time, return me everything in the map
    // 2) Second time, it should return me only the the change if there is any bundle version change

}

これで、このメソッドはすべてを Map として返すはずです。次のようなものです。

Key as FrameworkBundle and Value as 1.0.0
Key as BundleA and Value as 1.0.0
Key as BundleB and Value as 1.0.0
....
And for other Bundles like above

今、私に必要なのは-

  1. アプリケーションを初めて実行すると、上記のようにマップ内のすべてが返されます。
  2. また、15 分ごとに Cassandra データベースをチェックして、新しいバージョンのバンドルがあるかどうかを確認するバックグラウンド スレッドがあります。また、バンドルの新しいバージョンがある場合は、そのバンドル名とその新しいバージョンを返してください。どのバージョンにも変更がない場合は、2 回目は何も返さないでください。そして、これと同じプロセスが 15 分ごとに発生します。

つまり、最初だけを意味します。それ以外の場合はすべてを返したいです。バンドル バージョンに変更がない限り、何も返したくありません。

必要な情報を取得するための何らかのロジックを記述せずに、Cassandra がこれに関する情報を直接提供できるかどうかはわかりません。

Cassandra でこれを行うための最善かつ効率的な方法は何ですか? Cassandraデータベースから15分ごとにすべてのデータを取得してから、何らかのロジックを実行して、どのバンドルバージョンが変更されたかを調べたくありません..

4

1 に答える 1

1

cassandra はキー/バリュー ストアのようなものなので、これを実現するには適切な行キーが必要です。(列範囲) クエリを送信するときは、常に行キーが必要です。バンドル名もバージョンも事前に知っておく必要があるため、行キーとしてはあまり適していません。パーティショニングに使用できるアプリケーションの分類やその他の機能はありますか?

たとえば、別のフィールドとしてアプリケーション タイプ ID (商用、オープン ソース、プライベートなど) がある場合、クラスタリング/列キーがタイムスタンプであるテーブルを簡単に作成できます。行キーは、アプリケーション タイプ ID である可能性があります。新しいバージョンがある場合は常に、バージョン番号をアプリケーション / タイムスタンプに挿入します。次に、タイムスタンプを使用して範囲クエリを実行します。

  CREATE TABLE Bundles (
    bundle varchar,
    type varchar,
    ts timeuuid,
    version varchar,
    PRIMARY KEY (type, ts)
   );

初めて実行し、すべての新しいリリースを知りたい場合は、次を実行します。

cqlsh:test> SELECT * FROM Bundles WHERE 
    ...        type = 'OSS' and
    ...        ts < maxTimeuuid('2013-08-27 09:00:00');

(empty resultset)

これまで挿入がなかったので。

次に、ユーザー (または他のプロセス) が新しいリリースを挿入します。 「タイプ」という名前のソフトウェア カテゴリがいくつかあり、タイプが「フレームワーク」または「オープン ソース」など、ユース ケースに適したものであると仮定すると、次のようにデータを挿入できます。

cqlsh:test> INSERT INTO Bundles (bundle, type, ts, version) 
 VALUES ('SomeFramwork', 'OSS', now(), '0.1.0a');

これにより、新しい列が (now() の列キー値の下に) パーティション 1 (型、シャーディング キー) に格納されます。

15 分後、過去 15 分間のすべての新しいリリースを知りたい場合は、次のコマンドを実行します。

    cqlsh:test> SELECT type, dateOf(ts), bundle, version FROM Bundles WHERE
     type = 'OSS' and
     ts > minTimeuuid('2013-08-27 09:00:00')
     and ts < maxTimeuuid('2013-08-27 09:15:00');

     type | dateOf(ts)               | bundle       | version
    ------+--------------------------+--------------+---------
      OSS | 2013-08-27 09:14:27+0200 | SomeFramwork |  0.1.0a

タイプごとにクエリが必要になります。TimeUUD 型は、挿入が衝突しないことを保証します。

行が長くなりすぎる (20 億を超える) ことが心配な場合は、バケットを使用して行の長さを制限できます。

cql3 クエリを使用して Astyanax に挿入するには、次を使用できます。

    keyspace.prepareQuery(CF_BUNDLES).withCql(cql).execute();

ここで、cql は cql クエリで、CF_BUNDLES は ColumnFamily のインスタンスです。

Astyanax で上記で定義した cql クエリを使用してデータを取得するには、次を使用できます。

    CqlResult<String, String> result = keyspace
    .prepareQuery(CF_BUNDLES).withCql(cql).execute()
    .getResult();

これにより、結果を反復処理できます。

于 2013-08-26T12:02:02.883 に答える