1

では、ブラインド ウォーのゲームを作っているとしましょう。ユーザー A と B は x 個の兵士を持っています

現在 0 件の DB ドキュメントがあります。

ユーザー A が 50 人の兵士を送信して DB ドキュメントを作成 ユーザー B がユーザー A の後に 62 人の兵士を送信!

これにより、新しい DB ドキュメントが作成されます。

ユーザー A のドキュメントを検索し、それをユーザー B のドキュメントと比較して、両方のドキュメントを削除する最も効果的でスケーラブルな方法が必要です! (もちろん結果を返してから)

これが問題です!10,000 人以上のユーザーが比較的同時に兵士を派遣できる可能性があります。オーバーラップせずに上記のプロセスを正常に完了するにはどうすればよいですか?

私は開発に MEANstack を使用しているので、データベースでこれを行うことに限定されていませんが、明らかに WebApp は 100% 安全でなければなりません!

追加の情報や説明が必要な場合はお知らせください。この質問を更新します

-ありがとう

4

1 に答える 1

2

ここで頭に浮かぶことの 1 つは、必要と思われるすべての作業を行う必要はないということです。問題は、おそらくTTL インデックスキャップ付きコレクションの助けを借りて解決できるでしょう。次のエントリを検討してください。

{ "_id" : ObjectId("531cf5f3ba53b9dd07756bb7"), "user" : "A", "units" : 50 }
{ "_id" : ObjectId("531cf622ba53b9dd07756bb9"), "user" : "B", "units" : 62 }

したがって、2 つのエントリがあり、_id挿入したときにその値が返されます。したがって、最初は「A」には相手がいませんでしたが、「B」のエントリはその前のエントリと対戦します。

ObejctId は単調です。つまり、「次の」オブジェクトの値は、常に最後のオブジェクトよりも大きくなります。挿入されたデータを使用して、次のようにします。

db.moves.find({ 
    _id: {$lt: ObjectId("531cf622ba53b9dd07756bb9") }, 
    user: { $ne: "B" } 
}).limit(1)

これにより、直前に挿入された「移動」が現在の移動に与えられます。これは、以前に挿入されたものは現在のアイテムよりも値が小さい_idためです。また、ユーザー自身の動きに対して「遊んで」いないことを確認し、もちろん結果を 1 つのドキュメントのみに制限します。

したがって、「移動」は永遠に前進します。次の挿入がユーザー「C」によって行われると、ユーザー「B」から「移動」が取得され、ユーザー「A」はユーザー「C」から「移動」が取得されます。 "、 等々。

ここで「起こりうる」のは、「B」が次の「移動」を順番に行い、最後のリクエストと同じドキュメントを取得することだけです。しかし、それは「セッション」設計のポイントであり最後の「結果」を保存し、同じものを返さないようにするためです。そのため、設計で必要に応じて処理します。

「遊ぶ」にはそれで十分なはずです。しかし、「削除」の部分に行きましょう。

当然のことながら、何かを削除したいと「考え」ますが、最初の「ヘルパー」に戻ると、これは必要ないはずです。以上のことから、削除は「クリーンアップ」の要因にすぎないため、コレクションが膨大な割合に成長することはありません。

TTL インデックスを適用した場合、このチュートリアルの説明とほぼ同じ方法で、コレクション エントリがクリーンアップされ、一定期間後に削除されます。

また、何ができるか、特にキーの増加する性質を使用していること、_idおよびこれが多かれ少なかれ本質的に「キュー」であることを考慮すると、これを上限付きコレクションとして適用できます。そのため、いつでも保持する「移動」の最大サイズを設定できます。

2 つを組み合わせると、特定のサイズまで「成長」し、アクティビティが少し遅くなった場合に自動的にクリーンアップされるものになります。これにより、すべての操作が高速に保たれます。

肝心なのは、あなたが心配していた「削除」の並行性が、再生されたばかりのドキュメントを削除する必要性を実際に「取り除く」ことによって取り除かれたということです。クエリはシンプルに保たれ、TTL インデックスと上限付きコレクションがデータ管理の面倒を見てくれます。

これで、「ブラインド ウォー」という非常に同時進行するゲームに対する私の見方がわかりました。

于 2014-03-10T02:08:40.330 に答える