MMORPGなどの動的な世界を水平方向にスケーラブルにする方法はありますか?


11

500プレーヤー以上のオープンワールドで、20更新/プレーヤー/秒の速さでデータが変化することを想像してください。前回同様のMMORPGで作業したときはSQLを使用していたため、常にDBにクエリを実行できませんでした。代わりに、すべてのプレーヤーをDBからメモリにC ++オブジェクトとしてロードして使用しました。つまり、垂直方向にスケーリングされました。代わりにそのサーバーを水平方向にスケーラブルにすることは可能でしょうか?その量の更新を同時にサポートするように設計されたデータベースはありますか?


なぜデータベース内のプレーヤーを毎秒20回更新するのですか?
バロン

@バロンは私が混乱しているところです。データベースで更新せず、メモリのみで更新すると、マシンごとに異なる状態になります。しかし、DBの更新にはかなりのオーバーヘッドがあるので、その量の更新では実際には機能しないと思いますか?
MaiaVictor 2013年

2
本当に、実際には、さまざまなマシン(またはプロセス)が何百ものオブジェクトに対して20Hzの更新を必要とする場合、データベースを完全にバイパスし、メッセージングシステムを直接使用すると思います。しかし、あなたが本当に望んでいることは、あなたが本当に望んでいることではありません。あなたが欲しいのは、誰が何を知っている必要があるかというまともなスコープを持ち、その上にあるスコープ間でオブジェクトをきちんと転送する方法を持つことです。優れた回答を得るために、なぜ異なるマシン間で20Hzの更新が必要なのかという質問に答える必要があります。誰かが問題を調べる新しい方法を考えるかもしれません。
Patrick Hughes

@PatrickHughes何が必要かわからない。ゲームの仕組みを説明しているだけだ。キャラクターは毎秒2〜3タイル移動します。プレーヤーの狩猟はいくつかのモンスターに囲まれている可能性があるため、プレーヤーあたり1秒間に10タイル以上。次に、床の上、プレイヤーのバックパックの上に腐敗しているアイテムがあります。プレイヤーの方向に動く攻撃があり、モンスターの方向に動く攻撃があります。体力が低下し、マナが使用され、タイマーがプレイヤーに毒ダメージを与える。だから、物事は本当に速く変化します。これがゲームデザインです。このようなデザインを垂直方向に拡大縮小するにはどうすればよいですか?
MaiaVictor 2013年

1
私は少し前にこれをHackerNewsで見ました:paralleluniverse.co彼らはあなたのためにすべての空間セグメンテーション/配信を行うデータベースに取り組んでいます。私は内部で、彼らが以下の答えのすべてのことをしていると思います。
2013年

回答:


17

500人のプレーヤーがすべて通信するテストケース、つまり、20Hzで25万回の情報の流れが飛び交う。そのための内部帯域幅は、各メッセージを100バイトと仮定すると、約500MB /秒です。野心的ですね。特にプロセス間。

プレーヤーを100のグループに分離すると、20MB /秒に低下します。これが、MMOにゾーンがあり、それらのゾーンに影響の小さな気泡が続く理由です。

元の問題は、10人がすべてリアルタイム情報を共有しているが500人はすべて共有したい場合、それは通信リンクの指数関数的な成長であり、それをどのように回避できるかということです。幾何学的な進行を魔法のように消し去ることができる魔法の弾丸は、今まで聞いたことがありません。

データベースを使用して通信しないでください。それがメッセージングの目的です。データベースを使用して、取引を強制し、プレーヤーに失いたくない情報を保存します。私がよく知っているほとんどのMMOは、データベースを1〜10分ごとに動的に更新するか、ゾーンの移行やデザインの「セーフ」ゾーンに入るなどの便利なポイントでのみデータベースを更新します。

他のすべてのプレーヤーのバックパックの内容をリアルタイムで更新するには、遠く離れているすべてのプレーヤーのゲームのニーズを再設計する必要がある場合があります。

また、更新パターンを20Hzから距離に基づく速度に変更します。1マイル離れた人は、正確に230.6秒で1フィート移動したことを知る必要はありません。次に231.4秒で別の足を移動すると、10フィートごとに15フィート移動することに対処できます。秒。


素晴らしくて有益な答え、ありがとう。しかし、私は世界が非常に速いペースで変化している間、プレイヤーは彼のすぐ隣にいる他のプレイヤーしか見ることができないと付け加えるかもしれません。500人のプレイヤーがサーバーに情報を送信します。サーバーはこれらの500人のプレーヤーに定期的に情報を送信します。私が見るように、それは線形です。ただし、要点は4番目の段落にあります。データベースをストレージとしてのみ使用する場合は、データをメモリにロードします。マシンのメモリにデータをロードする場合、非同期のバージョンの世界を作成しています。それは私が得ないものです。
MaiaVictor 2013年

1クライアントの場合:1メッセージアウト+ 1メッセージイン=2。2クライアントの場合:2メッセージアウト、2メッセージイン=4。3クライアントの場合:3メッセージアウト、3メッセージイン= 9。これは次のようなものです。ステータスメッセージを送信し、サーバーが結果を私と他の2つのクライアント(1 in、3 out)に送信し、3つのクライアントがすべてそれを実行します(1 in 9 out)。3つのクライアントの1つだけでは線形に見えますが、システムの合計スループットについては、それをすべてのクライアントで乗算します。非同期については、同じ物理ボックス上のプロセスでさえ、ステータスメッセージが作成されて送信されるまで同期されません。それは、パイプが空になる場所、ローカルRAMまたはネットの問題です。
Patrick Hughes

5

関心領域のフィルタリングを使用します。ワールドが3つのサーバーに分割されており、サーバー1の領域がサーバー3の領域の近くにない場合、エンティティに関する情報を共有する必要はまったくありません。

同様に、単一のサーバーでは、関連情報のみをクライアントに送信します。プレーヤーAがマップのプレーヤーBとはまったく反対側にいる場合、Bに関する更新をAに送信する、またはその逆の理由はありません。

連続的な世界に複数のサーバーがある場合、サーバー1のエンティティに近いサーバー2のエッジ近くにエンティティがあります。エンティティの「権限のある」サーバーから他のサーバーに更新を送信できます(適切な場合)。 、同様にメッセージを適切な権限のあるサーバーに転送します。

はい、この場合、1つのサーバーが特定のエンティティに対してわずかに古くなります。それを解決しようとしないでください。ただそれに対処してください。エンティティが少し古くなっていると想定します。エンティティを正式に所有しているサーバーでのみ、最新の情報を必要とするロジックを実行します。エンティティが別のエンティティに影響を与える場合は、メッセージを送信し、処理されてビューが更新される前に、複数のゲームロジックティックがかかる可能性があると想定します。

この設計により、単一サーバーのスレッド化もはるかに簡単になります。エンティティは別のものを直接変更してメッセージを送信するだけでなく、ローカルのサーバーごと/スレッドごとのプロキシキャッシュはわずかに古くなっていると想定する必要があります。

たとえば、エンティティAがエンティティBを攻撃する場合、Bの存続期間を確認せず、0に達した場合は死のメッセージを送信します。「破損」メッセージを送信し、Bの権限のあるサーバーに処理させてから、エンティティAが気にした場合、後でサーバーBから送信された「エンティティダイ」メッセージ。

同じことが、大規模でスケーラブルな非ゲームアプリケーションにも当てはまります。中央データベースは、魔法のようなインスタント共有テクノロジーではありません。高スループットを維持するために、2つのサーバーは非同期でバッチでメッセージと通信する必要があります。したがって、AMPQなどのテクノロジーの人気が高まっています。データベースはストレージ用であり、必要に応じて同期をサポートします。データベース自体が同期または通信を目的としているためではなく、通信に使用できるようにします。


おかげで、これは私の残りの疑問のほとんどを終わらせました。また、エリアではなくプレイヤーごとにサーバーを分離するという考えを教えてくれました。これはよりスムーズに見えます。各サーバーがxプレーヤーを処理します。私は本当にこれが好きです!これは使用されていますか?また、もう1つだけあります。上記で質問したように、新しいNoSQLデータベースであるCouchbaseについて学びました。非常に速い書き込み/読み取り速度を除いて、CouchDBと同じように想定されています。1秒あたり最大200kの更新!たぶん、これはそのような「リアルタイム共有世界モデル」として実際に機能するでしょうか、それともまだ機能しないのでしょうか?
MaiaVictor 2013年

サーバーの通常の粗い「シャーディング」以外に、その手法が実際に使用されているかどうかはわかりません。プレイヤーと地理的なエリアでそれを行うだけでは、各サーバーがさまざまなエリアのセット全体で非常に多数のエンティティを認識する必要があり、サーバーの負荷が増加し、サーバー間の通信が大幅に増加する可能性があります。領域ごとに行うと、混雑した領域でサーバーが過負荷になる可能性があります(その場合、動的に領域を分割して結合できます)が、各サーバーには関連する非プレーヤーエンティティとジオメトリのセットが少なくなり、追跡できます。
Sean Middleditch 2013年

@Dokkat:各サーバーが主にゲームの世界の特定の部分のプレーヤーを処理するような「ソフトエリア」がある可能性があるかもしれませんが、プレイヤーが遠く離れすぎている場合は、プレーヤーを透過的に別のサーバーに渡します。元のサーバーの地域。プレイヤーに気付かれないように、ハンドオーバーがスムーズであることを確認する必要があります。インタラクティブなプレーヤーのクラスターを、リージョン境界にある場合でも、同じサーバー上に維持するために、いくつかの優れた適応技術を使用することもできます。
Ilmari Karonen 2013年


2

データベースを、常にすべてのものをすべて保存する、ある種のリアルタイムの共有世界モデルと考えないでください。お気づきのとおり、これは機能しない可能性があります。

代わりに、データベースを自動更新された保存ファイルのように扱います。たとえば、プレーヤーがログインまたはログアウトしたとき、またはゾーンからゾーンに移動したとき、または重要ではない重要なことが起こったときなど、データベースをたまに更新します。サーバーがクラッシュした場合は失われます。

実際のリアルタイムの世界の状態は、元の例と同様に、ゲームサーバーのメモリに保持されます。さて、水平スケーリングの秘訣は、すべてのサーバーがすべての瞬間にすべてを知る必要があるわけでないということです。たとえば、プレーヤーAがサーバーAのゾーンAでプレイしている場合、ゾーンBを実行しているサーバーBは通常、プレーヤーAがバックパックに何を持っているかを知る必要はありません。何らかの理由でそれを知る必要ある場合(たとえば、ゾーンBのプレーヤーBはAに何らかのリモートスパイスペルをキャストするため、他のサーバーにその情報を要求することができます

これには、サーバーに明確な責任を割り当てる必要があるため、サーバーBがプレーヤーAのバックパックについて知りたい場合、どのサーバーがその上に信頼できる情報を持っているかを知ることができます。また、サーバーBがサーバーAに単に通知できるように、なんらかの更新サブスクリプションメカニズムを含めることもできます。「プレーヤーAを誰かがスパイしているので、他のことを言うまで、彼らが行うすべてのことを更新してください。」また、プレーヤーがどこにいても知る必要がある重要なグローバルイベントのために、なんらかのグローバルブロードキャストシステムを含める必要があります。もちろん、このようなイベントもデータベースに記録する必要がありますが、それらのイベントをすべてのサーバーに積極的にブロードキャストすることで、サーバーはデータベースの更新をポーリングし続ける必要がなくなります。


素晴らしい答えです!これはまさに私が求めていたものでした、ありがとう。したがって、おそらく重要なのは、サーバーを領域に分割し、ロジックをメモリ上に維持することです。ただし、追加することがあります。新しいNoSQLデータベースであるCouchbaseについて学んだところです。非常に速い書き込み/読み取り速度を除いて、CouchDBと同じように想定されています。1秒あたり最大200kの更新!たぶん、これはそのような「リアルタイム共有世界モデル」として実際に機能するのでしょうか、それともまだ機能しないのでしょうか。
MaiaVictor 2013年

@ドックカットいいえ、それはしません。Couchbaseは魔法ではありません。
フィリップ

2

他の回答では、データベースの使用方法を指摘し、データベースを通信に使用しないことを指摘しています。検討すべきもう1つの側面は、情報を他のエンティティに伝達する方法に基づいて更新を分類することです。サーバーへの通信をスコープするのではなく、メッセージングを分散し、エンティティ間で更新を通信するためにpubsubメカニズムを使用できます。たとえば、近くにいる人に応じて場所の扱いを変えることができます。

  • 正確なリアルタイムの位置が半径R内で役立つ場合があります
  • 精度が低く、頻度が低い位置の更新は、半径2 * R内で役立ちます
  • 半径2 * Rを超える位置情報は不要かもしれません

半径2 * R(またはエンティティの更新レートと最大速度に基づいてその倍数)内のエンティティを定期的にスキャンし、エンティティを他のエンティティの正確または不正確な位置フィードにサブスクライブすることにより、エンティティの位置情報を伝達する場合があります。

情報の種類ごとに異なる戦略を作成したり、共通のものを同じメッセージキューにグループ化したり、異なるエンティティに移動する必要があるメッセージ用に異なるキューを作成したり(または、最も広範なエンティティのセットに送信して、メッセージが破棄された場合にメッセージを破棄したり)役に立たない)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.