3

私はもともとリレーショナルスタイルのデータストアに精通しています。私は現在NoSQLを調べており、そのユースケースについて学ぼうとしています。これが最近私を悩ませているものです。

典型的なNoSQL製品を使用して次の操作をどのように行いますか?

  • 複数の入力を読み取ります
  • それらの新しい値を計算します(各出力はすべての入力に依存します)
  • 値を書き戻します

他の問題に関する過去の経験からのこの例は次のとおりです。さまざまなユーザーアカウントを持つWebゲームがあります。ユーザーはお互いに攻撃を開始できます。攻撃の公式は、入力とランダム性の両方に基づいて相互の結果を決定する複雑なブラックボックスゲームロジックです。ゲームで実行される一連の攻撃のシリアル化に関して、攻撃がアトミックに発生し、入力が出力と同様に一貫した時点を反映するように強制する必要があります。

重要なことは次のとおりです。

  • すべての出力は、分解できない複雑な方法ですべての入力に依存します(つまり、これを教科書の銀行口座からトランザクション元帳の例に変換することはできません。ログ先行書き込みのみを使用することはできません)。
  • 言い換えれば、P1 + = $ 10、P2-=$10を実行していません
  • もっと似ているのは、一貫したスナップショットが必要な場合に、[議論のために] [本質的に複雑/既約](P1、P2)=(sha1(P1 + P2)、sha1(P1-P2))を実行していることです。 P1とP2の値の比較[特定の行が実際のゲームの良い例であることは言うまでもありません]
  • 入力はレコードの小さなサブセットの任意の選択になるため、複合レコードだけを使用することはできません。
  • 外部のオブザーバーは、すべての操作の前または後のいずれかで均一/一貫した状態を確認しますが、その間は確認しません。

私の特定の例は、私たちが遭遇した問題でした。実際にはリレーショナルデータベースを使用していましたが、本来あるべきトランザクション機能を使用していませんでした。その結果、互いに攻撃し合うオンラインプレーヤーは、誤った結果を生成し、両方の攻撃者にファントムリソースを生成する傾向がありました。

リレーショナルモデルでは、トランザクションを使用してこれを実行します。そういえば、これは教科書の取引例かもしれません。

NoSQLでこれを達成するにはどうすればよいですか?

これが私がSOや他の場所で見た、この特定のインスタンスには不向きだと思う答えです。

  • 競合状態の可能性を無視する
  • これが問題にならないようにゲームを再設計します
  • データストアを使用して、2PC、パン屋のアルゴリズムなどを手動で実装します
  • 外部ロックサービスを使用する

...それらのいずれかまたはすべてが良い解決策であると思われる場合でも、その方法と理由を教えてください。

この種のことを実際に実装する方法について、いくつかの指針をいただければ幸いです。

ありがとう!

4

1 に答える 1

2

このトピックに関してMongoDBについて知っておく必要がある2つのことは次のとおりです。

  • アトミック性の単位は単一のドキュメントです。
  • トランザクションはありませんが、シミュレートできます。

このことを念頭に置いて、この種のことはMongoDBの強みではありません。これを自分で指摘すると、本質的にはトランザクションです。

ただし、これをモデル化する場合は、ドキュメントが次のようになっている攻撃のコレクションを作成することから始めることができます。

{
  attacker: {user_document},
  attackee: {user_document},
  in_progress:  boolean (true or false),
  outcomes: [array of results based on calculation]
}

攻撃を開始するには、両方のユーザーIDを含むクエリドキュメントを持つアップサートを使用してfindAndModifyを使用して攻撃コレクションをクエリします。存在する場合、新しい攻撃は作成されません。存在しない場合は、ドキュメントを挿入し、in_progressをtrueに設定することで攻撃を開始します。そこに必要なすべてのユーザーの詳細を入力します。

次に、ブラックボックスの計算を行い、結果配列への攻撃の結果として両方のユーザードキュメントに発生する必要がある一連の更新をプッシュし、in_progressをfalseに設定します。

終了したら、結果をユーザーコレクションに1つずつ適用します。

これ以上結果が存在しない場合は、攻撃ドキュメントを削除して、新しい攻撃を開始できるようにします。

要件を考えると、これが完全に理にかなっているのかどうかはわかりませんが、うまくいけば、これがどのように実行できるかを考えるのに役立ちます。

于 2012-05-29T16:14:59.070 に答える