問題:
アプリケーションの nosql データ ストアとして cassandra を使用する予定です。私が持っているユースケースの 1 つは、ユーザーの「残高」を更新することです。各ユーザーの残高がキー UID_balance として保存されているとします。アプリケーションで複数のユーザーの残高を更新したい場合、原子性をどのように処理すればよいでしょうか?
ある時点で、アプリケーションは基本的に次のことを行うと思います。
1. for each user u
2. current_balance = read_users_balance(u);
3. new_balance = current_balance + delta_for_user(u);
4. write_users_balance(u, new_balance);
5. end
ここで、いくつかの問題があります。
- cassandra への接続が中断され、コードが一部のユーザーの残高のみを更新する原因となる場合があります。
- ステップ 2 と 4 の間に、ユーザーの残高を更新する可能性のある別のプロセスが存在する可能性があり、古い残高を更新して、ユーザーの残高を「破損した」状態のままにします。
RDBMS は ACID プロパティを提供するため、これらの問題を解決しますが、Cassandra は提供しません。Cassandra はごく最近 (2012 年 10 月)、Atomic Batch の提供を開始しました。それがこの問題の正しい解決策であるかどうかはわかりません。
考えられる解決策:
これは私が友人とブレインストーミングしたものです。ユーザーの残高を実際に更新するのではなく、更新デルタを別のレコードに追加するレコードを作成します。例えば:
UID1_balance = {100}
UID1_deltas = {10,20,-40}
現在の残高を取得するには、残高にデルタを適用するだけです。デルタをユーザーの残高に適用し、デルタ リストを削除するオフライン プロセスを使用できます。
このソリューションは機能し、破損状態の可能性を減らしますが、これはやり過ぎだと思います。この問題を解決するより良い方法はありますか?