負荷を軽減するために、単一のシャードまたはレルムの処理を複数のサーバーで実行できることがMMOの一般的な要件だと思います。すべてのプレイヤーとすべてのNPCが相互作用できる統一された一貫した世界を維持しながら、これをどのように行うことができるのか興味があります。
私の質問は、MMOでロードバランシングをどのように達成するかです。
このテーマに関する知識を向上させる方法に関するリンク、書籍、または一般情報も歓迎します。
負荷を軽減するために、単一のシャードまたはレルムの処理を複数のサーバーで実行できることがMMOの一般的な要件だと思います。すべてのプレイヤーとすべてのNPCが相互作用できる統一された一貫した世界を維持しながら、これをどのように行うことができるのか興味があります。
私の質問は、MMOでロードバランシングをどのように達成するかです。
このテーマに関する知識を向上させる方法に関するリンク、書籍、または一般情報も歓迎します。
回答:
これをできるだけシンプルに保ち、インターフェイスを適切に定義して文書化してください。実稼働環境で複雑なシステムを保守およびデバッグすると、簡単に地獄になります。したがって、単純なアプローチと複雑なアプローチがある場合は、複雑なアプローチに進む前によく考えてください。
最初のステップは、静的コンテンツ、認証、ローカルチャット、グローバルチャットチャネル、リージョナルチャットチャネル、フレンドリスト、ギルド、バッグ/インベントリ、オークションハウス、グローバルマップ、ワールドなどのサービスとその依存関係を特定することだと思います。
次に、これらの各サービスについて、クライアントが直接サービスにアクセスできるかどうかを決定しました。たとえば、クライアントがグローバルチャットチャネルを担当するサーバーと直接対話できるようにするのは非常に簡単です。ワールドサーバーは、チャットメッセージにまったく関与する必要はありません。リージョナルチャットも同じ方法で実装できますが、ワールドサーバーは、プレイヤーがリージョンを変更したときにチャットサーバーに通知する必要があります。繰り返しますが、彼らはメッセージを気にする必要はありません。
3番目のステップは、サービス内の負荷分散について考えることです。たとえば、グローバルおよび地域のチャットチャネルは、名前に基づいて複数のサーバーに分割できます。この分割をクライアントにハードコーディングせずに、ルックアップサービスを提供することをお勧めします。
最も難しい部分は通常、ワールドサーバーです。そのため、単純なアプローチから始めます。クライアントが現在いる地域を担当するサーバーと直接対話できるようにすることをお勧めします。そのため、ログインまたは地域を越えたときに、クライアントが接続するサーバーに通知する必要があります。
簡単なアプローチは、世界を独立した地域に分割することです。独立した地域では、プレイヤーはある部分から別の部分を見ることはできず、モンスターは部分を横切ることができません。これらの地域は、外の世界の風景や物語に基づいてプレイヤーが見る地域とは異なります。通常、ほとんどのモンスターはダンジョンにあり、プレイヤーはダンジョンに入るためにゲートウェイを通り抜けなければならないことを受け入れる傾向があります。特に、これらのダンジョンがプレイヤーグループごとにインスタンス化される場合。外の世界の他の例は、高山に囲まれた異なる大陸と谷です。
連続世界のクライアントのニーズを何情報:それはうまくそれを計画するために理にかなっているようなアプローチは、すぐには本当に複雑になりますか?サーバーはどの情報を共有する必要がありますか?プレイヤーは、ほとんど同じリージョン内のオブジェクト(モンスターやNPCを含む)とのみ対話します。ゾーンの境界線からクリック範囲外にオブジェクトを配置することにより、チートできます。これは、クライアントが隣接ゾーンの読み取り専用情報にほとんど関心があることを意味します。これらの場合、ゾーンサーバーは、プレーヤーが隣接ゾーンに接続するのに十分な距離にあることを確認する許可チェックを除き、何も調整する必要はありません。
これにより、オブジェクトやアクションがサーバーの境界を越えなければならない困難なケースが非常に少なくなります。矢印や呪文などの場合はパフォーマンスが重要なので、これは良いことです。戦闘を攻撃と防御に分けるのは良い考えかもしれません。そのため、スペルキャスターのサーバーは、キャスターの位置を含む攻撃パラメーターを定義します。防御側のサーバーは、攻撃に関するメッセージを取得し、影響を計算します。攻撃者のサーバーは影響について知る必要はありません。クライアントは、読み取り専用接続を使用してそれについて学習します。
プレーヤーモデルの複雑さによっては、別のサーバーに転送するのに数秒かかる場合があります(Second Lifeにはこれに大きな問題があります)。この問題は、プレーヤーが仮想境界に近づいたときに事前に転送を準備することで軽減できます。そのため、実際のハンドオーバーが発生したときに、ほとんどのプレーヤーデータが宛先サーバーに既にキャッシュされています。
ほとんど依存せずにサーバー間で分割できるさまざまなサービスを定義することにより、問題を分割します。次のステップとして、重要なサービス内で負荷分散を行う方法を調べます。関連するサーバーに直接接続するようにクライアントに指示することにより、クライアントに分散作業を委任します(明らかにサーバーはアクセス許可を確認する必要があります)。できるだけシンプルに保ち、さまざまなサービスとサーバーの責任を文書化し、デバッグ出力を有効にするオプションを提供します。
PS:これらの手法のいくつかは、信頼性を向上させるために使用できます。また、多くのサーバーを使用すると、物事が壊れるリスクがはるかに高くなるため、この点に留意してください。ソフトウェアだけでなく、ハードウェアレベルでもです。
一般的に、世界はいくつかの小さな地域に分割されています。これらの各リージョンは通常、独立したサーバープロセス(WoWのワールドサーバーまたはEveのSolノード)であり、任意の数のマシンで実行できます。一部のゲームでは、マップ間に明示的なドアがあり(イブ、STO、ギルドウォーズ)、他のゲームではこれをさらに隠そうとします(WAR、フリーレルム)よりシームレスなアプローチを選択した場合は、通常、2つのサーバー間の境界に近づいていることを検出し、2つのプロセスがハンドオフをネゴシエートします。おそらくこれの説明を探すのに最適な場所は、セルタワーが移動するハンドセットのハンドオフを行う方法です。1つのマップ(Jita、Ironforge、Earth Space Dock)の負荷が非常に大きくなる場合、個々の機能を他のサーバー(AI、プレーヤー管理の特定の部分)が、これは最初から組み込まれている必要がありますか、いくつかの深刻な改造が必要です。ほとんどの場合、より優れたハードウェアを購入してこれらの少数のマップ専用にする方が、コスト効率が高くなります。
負荷を軽減するために、単一のシャードまたはレルムの処理を複数のサーバーで実行できることがMMOの一般的な要件だと思います。すべてのプレイヤーとすべてのNPCが対話できる統一された一貫した世界を維持しながら、これをどのように行うことができるのか興味があります。
おそらくあなたが思うほど一般的ではありません。少なくとも、1つのシームレスな世界が複数のサーバーによって同時に管理されていると考えている場合は別です。
完全に別々のシャードをカウントするのではなく、オンラインゲームを分割できる2つの方向があり、「水平」と「垂直」と見なすことができます。
明らかに、これらのアプローチは直交しており、2つを組み合わせることができます。実際、ゲームプレイとは別のマシンにログイン/認証をプッシュすることは非常に一般的であり、ゲームの世界に関係なくチャットやその他の重要ではない通信をファーム化することは非常に一般的です。分割されます。
しかし、全体として、地理的なパーティションがある場合、ほとんどのゲームでは、うまくやることが難しいため、これらの境界を越えてやり取りすることを避けています。代わりに、他の方法を使用して、実際にはそうではない場合でも、すべてが同じシャードにあり、同じサーバー上にいるように見せます。例えば。-ゾーン間またはある大陸から別の大陸への移行時に、サーバーの変更をカバーするロード画面またはその他のアニメーションが変更されます。-別のダンジョンまたはレイドインスタンスは、他の全員から隔離されています。これらはシャード内のシャードのようなもので、別のサーバーで簡単に実行できるため、負荷分散に役立ちます。
WoWの権威と話すことはできませんが、彼らは上記のほぼすべてを実行していると思います:インスタンス化、相互作用することができない別々の地理的領域、ある種のポータル、別々のバックエンドおよび認証サーバーによって結合されています。WoWレルムでは、特定のレルムで一度に1000〜10000人のプレイヤーがオンラインになります。これは上記のスキームで簡単に管理できます。
しかし、単一の巨大な世界があり、プレイヤーが1つのサーバーに隣接するサーバーのプレイヤーと対話できるようにする必要があると仮定しましょう。これは理論的には簡単です-最初に、サーバーは境界に沿ってオブジェクトの詳細を共有するために協力する必要があります(したがって、1つのサーバー上のオブジェクトは別のプロキシ表現を持つことがあります)。次に、すべてのロジックをメッセージ受け渡しに変更します。必要に応じて、プロキシから信頼できるソースにルーティングされるメッセージ。メッセージはサーバー間またはサーバー内でかなり透過的に渡すことができるため、1つのアプローチがすべてのシステムに適合します。
ここでの問題は、以前は単純なロジックがメッセージに変換されると非常に複雑になる可能性があることです。両方のプレイヤーが1つのサーバー上にいるときに安全かつアトミックに発生する2プレイヤーのトレードは、メッセージを送受信するたびにプロセスが長くなり、送信ごとに再検証し、1人のプレイヤーが悪用できないようにするためのセーフガードを設けますもう1つは、メッセージの移動中に取引を変更することです。メッセージが到着するまでに他のプレーヤーがまだ存在しているとは想定できないため(死んだり、ログアウトしたりする可能性があるため)、コードは非常に複雑になります。そして、これは、取引、戦闘、グループ化、オークション、略奪、トレーニングなど、2つ以上のエンティティが相互作用または協力できるほとんどすべてのシステムに適用されます。
これらの問題は克服できないものではありませんが、ほとんどのゲームでは、他の手段で負荷を共有し、すべてのゲームロジックを1つのサーバーに保持できる場合、試してみる価値はありません。そのため、現在のほとんどすべてのゲームが代わりにそのルートをたどります。
MMOサーバーの負荷分散には多くの方法があります。処理されるデータの範囲は非常に広いためです。私はプロセスビンツリー方式を好みます。
グローバルサーバーは、一度に複数のユーザーを処理できるプロセスビンにユーザー接続を渡します。プロセスビンはすべての複雑な処理を行い、グローバルチャットやポジショニングなど、グローバルに関連するデータでグローバルサーバーにのみ応答します。この方法は、リージョンの人口が大きく異なるため、リージョンサーバーよりもはるかに優れたバランスをとりますが、ユーザー処理全体は、ほとんどの部分で自然にバランスが取れるように十分に変化します。
グローバルサーバーを介して基本的な負荷分散を行うだけで、プロセスビンが特定のメモリ/ CPU使用量に達すると、新しいプロセスビンサーバーを起動します。