1

複合列で実装されたCassandra行にイベントのリストを格納するとします。

{
    event:123 => 'something happened'
    event:234 => 'something else happened'
}

私にとってはほとんど問題ありません。私が理解している限り、これは一般的なパターンです。eventjsonizedリストを含む単一の列がある場合と比較すると、最初に読み取ってから書き戻すことなく新しい項目をリストに追加するのが簡単であるため、スケーリングが向上します。

ただし、次の2つの要件を実装する必要があります。

  • 最後に追加したイベントが同じである場合、新しいイベントを追加したくありません。
  • 最後のイベントをN個だけ残しておきたい。

可能な限り最高のパフォーマンスでそれを行う標準的な方法はありますか?(ストレージスキーマの変更はすべて問題ありません)。

4

1 に答える 1

2

物事がすでに存在するかどうかを確認すること、または存在するものの数を確認して余分な項目を削除することは、どちらも読み取り-変更-書き込み操作であり、Cassandraの制約にうまく適合しません。

N個の最後のイベントのみを保持する1つの方法は、範囲クエリを実行して最後のN個を読み取ることができるようにそれらが順序付けられていることを確認することです(たとえば、列キーの前にタイムスタンプ/ TimeUUIDを付けます)。これは、別のプロセスとして実行する必要がある古いイベントを削除しませんが、このようにすることで、データをクエリするコードは最後のNのみを参照します。これは、正しく解釈する場合の実際の要件です。古いイベントのガベージコレクションは、二度と必要とされないものを保持しないようにするための最適化にすぎません。

要件が厳密なNイベントではなく、Tより古くないイベントの場合は、もちろんTTL機能を使用できますが、これはオプションではないと思います。

最初の要件は注意が必要です。書き込みの前に読み取りを実行して、アイテムがあるかどうかを確認できますが、それは遅くなります。また、Cassandraの外部で何らかのロックを実行しない限り、2人のライターが読み取りとその後の両方を実行しないという保証はありません。どちらも書き込みを行うため、どちらも他方の書き込みを認識しません。たぶんそれはあなたにとって問題ではありませんが、それを回避する良い方法はありません。CassandraはCASを行いません。

Cassandraを使用するときに同様の状況を処理した方法は、書き込まれたもののアプリケーションノードにキャッシュを保持し、書き込む前にそれを確認することです。次に、各アプリケーションノードが同じ行のすべてのイベントを認識し、同じ行のイベントが複数のアプリケーションノードに分散されていないことを確認する必要があります。これを行う1つの方法は、アプリケーションノードの前にメッセージキューシステムを配置し、データベースで行キーとして使用するのと同じキーでイベントストリームを複数のキューに分割することです。

于 2013-03-20T20:12:47.413 に答える