Cassandraでの時間範囲の保存

cassandra
Cassandraでの時間範囲の保存

後で効率的に取得できるように、時間範囲に関連付けられたデータを保存する良い方法を探しています。

データの各エントリは、「(開始時刻、終了時刻、値)」として簡略化できます。 後で `(x、y)`の範囲内にあるすべてのエントリを取得する必要があります。 SQLでは、クエリは次のようになります

データから値を選択WHERE starttime ⇐ x AND endtime> = y

Cassandraのデータの構造を提案すると、このようなクエリを効率的に実行できますか?

  6  1


ベストアンサー

これは、効率的にモデル化するのは奇妙に難しいことです。

Cassandraのセカンダリインデックスを使用することは(現時点では残念ながらまだ必要なダミーのインデックス付きの値と共に)最適な選択肢だと思います。 イベントごとに1行を使用し、「開始」、「終了」、「ダミー」の少なくとも3つの列を使用する必要があります。 これらのそれぞれにセカンダリインデックスを作成します。 最初の2つはLongTypeで、最後はBytesTypeです。 詳細については、http://www.riptano.com/blog/whats-new-cassandra-07-secondary-indexes [セカンダリインデックスの使用に関するこの投稿]を参照してください。 セカンダリインデックスクエリの少なくとも1つの列でEQ式を使用する必要があるため(不幸な要件ですが)、EQは常に「0」に設定できる「ダミー」になります。 (これは、EQインデックス式がすべての行と一致し、基本的に何もしないことを意味します。)イベントデータの残りを、開始、終了、ダミーと並んで行に格納できます。

Python Cassandraクライアントであるhttps://github.com/pycassa/pycassa[pycassa]では、クエリは次のようになります。

from pycassa.index import *
start_time = 12312312000
end_time = 12312312300
start_exp = create_index_expression('start', start_time, GT)
end_exp = create_index_expression('end', end_time, LT)
dummy_exp = create_index_expression('dummy', 0, EQ)
clause = create_index_clause([start_exp, end_exp, dummy_exp], count=1000)
for result in entries.get_indexed_slices(clause):
    # do stuff with result

他のクライアントにも同様のものがあるはずです。

私が最初に考えた代替手段は、ほとんど常に悪いことであるOrderPreservingPartitionerに関係していました。 インデックスの場合、開始時刻を行キーとして使用し、終了時刻を列名として使用します。 その後、start_key = start_timeおよびcolumn_finish = finish_timeを使用して範囲スライスを実行できます。 これにより、開始時刻以降のすべての行がスキャンされ、finish_timeより前の列を持つ行のみが返されます。 あまり効率的ではなく、大きなマルチゲットなどを行う必要があります。 ノードはローカルデータのみにインデックスを付け、定型的なインデックスコードのほとんどが自動的に処理されるため、組み込みのセカンダリインデックスアプローチの方が優れています。

6


タイトルとURLをコピーしました