Wie wird der Lastenausgleich in MMOs erreicht?

26

Ich glaube, dass MMOs häufig verlangen, dass die Verarbeitung für einen einzelnen Shard oder Realm über mehrere Server erfolgen kann, um die Auslastung zu verringern. Ich bin gespannt, wie dies unter Beibehaltung einer einheitlichen, konsistenten Welt geschehen kann, in der alle Spieler und alle NPCs interagieren können.

Meine Frage ist, wie Lastenausgleich in MMOs erreicht wird?

Alle Links, Bücher oder allgemeine Informationen zur Verbesserung meiner Kenntnisse zu diesem Thema sind ebenfalls willkommen.

CiscoIPPhone
quelle

Antworten:

30

Versuchen Sie, dies so einfach wie möglich zu halten und die Schnittstellen klar zu definieren und zu dokumentieren. Das Warten und Debuggen eines komplexen Systems in der Produktion wird leicht zur Hölle. Wenn es also einen einfachen und einen komplexen Ansatz gibt, überlegen Sie zweimal, bevor Sie mit dem komplexen Ansatz beginnen.

Services definieren

Ich denke, der erste Schritt besteht darin , Dienste und ihre Abhängigkeiten zu identifizieren : Statischer Inhalt, Authentifizierung, Lokaler Chat, Globale Chat-Kanäle, Regionale Chat-Kanäle, Freundesliste, Gilden, Tasche / Inventar, Auktionshaus, Globale Karte, Welt, ...

Dann wird für jede dieser Dienstleistungen entschieden, ob der Kunde direkt mit ihnen sprechen darf. Zum Beispiel ist es ziemlich einfach, den Client direkt mit den für globale Chat-Kanäle verantwortlichen Servern sprechen zu lassen. Die Server der Welt müssen überhaupt nicht an Chat-Nachrichten beteiligt sein. Regionaler Chat kann auf die gleiche Weise implementiert werden, aber die Server der Welt müssen den Chat-Servern mitteilen, wann Spieler die Region wechseln. Auch hier müssen sie sich nicht um die Nachrichten kümmern.

Der dritte Schritt ist das Überlegen des Lastenausgleichs innerhalb eines Dienstes . Beispielsweise können globale und regionale Chat-Kanäle basierend auf ihrem Namen auf mehrere Server aufgeteilt werden. Es ist wahrscheinlich eine gute Idee, diese Aufteilung in den Client nicht hart zu codieren, sondern einen Suchdienst bereitzustellen.

Weltserver

Der schwierigste Teil sind normalerweise die Server der Welt , daher beginne ich mit einem einfachen Ansatz. Es ist wahrscheinlich eine gute Idee, den Client direkt mit dem Server zu sprechen, der für die Region verantwortlich ist, in der er sich befindet. Beim Anmelden oder Überqueren der Region muss dem Client mitgeteilt werden, mit welchem ​​Server er sich verbinden soll.

Der einfache Ansatz besteht darin, die Welt in unabhängige Regionen aufzuteilen . Mit unabhängigen Regionen meine ich, dass ein Spieler nicht von einem Teil in einen anderen schauen kann und Monster keine Teile überqueren können. Diese Regionen unterscheiden sich von den Regionen, die der Spieler aufgrund der Landschaft und der Geschichte der Außenwelt sieht. Normalerweise befinden sich die meisten Monster in Dungeons und die Spieler neigen dazu zu akzeptieren, dass sie durch ein Tor gehen müssen, um einen Dungeon zu betreten. Vor allem, wenn diese Dungeons pro Spielergruppe instanziiert werden. Andere Beispiele auf der Außenwelt sind verschiedene Kontinente und Täler, die von hohen Bergen umgeben sind.

Ein kontinuierlicher Weltansatz wird sehr schnell komplex, daher ist es sinnvoll, ihn gut zu planen: Welche Informationen benötigt der Kunde? Welche Informationen müssen die Server teilen? Der Spieler interagiert meist nur mit den Objekten (einschließlich Monstern und NSCs) in derselben Region. Sie können betrügen, indem Sie Objekte außerhalb des Klickbereichs vom Zonenrand platzieren. Dies bedeutet, dass der Kunde hauptsächlich an Nur-Lese-Informationen für benachbarte Zonen interessiert ist. In diesen Fällen müssen die Zonenserver bis auf die Berechtigungsprüfung nichts koordinieren, dass der Player nah genug ist, um eine Verbindung zu einer benachbarten Zone herzustellen.

Dies lässt nur eine sehr kleine Anzahl von schwierigen Fällen übrig, in denen Objekte oder Aktionen eine Servergrenze überschreiten müssen. Das ist gut so, denn solche Fälle wie Pfeile und Zauber sind leistungskritisch. Es kann eine gute Idee sein, den Kampf in Angriff und Verteidigung zu unterteilen. Der Server eines Zaubernden definiert also die Angriffsparameter einschließlich der Position des Zaubernden. Der Server des Verteidigers erhält die Nachricht über den Angriff und berechnet die Auswirkungen. Der Server des Angreifers muss die Auswirkungen nicht kennen. Der Client erfährt davon über seine Nur-Lese-Verbindung.

Je nachdem, wie komplex Ihr Playermodell ist, kann es einige Sekunden dauern, bis es auf einen anderen Server übertragen wird (Second Life hat ein großes Problem damit). Das Problem kann behoben werden, indem der Transfer im Voraus vorbereitet wird , wenn sich der Spieler einer virtuellen Grenze nähert. Damit die meisten Player-Daten bereits beim eigentlichen Handover auf dem Zielserver zwischengespeichert sind.

Zusammenfassung

Teilen Sie das Problem auf, indem Sie verschiedene Dienste definieren, die auf Server mit geringen Abhängigkeiten aufgeteilt werden können. Schauen Sie sich im nächsten Schritt an, wie Sie den Lastausgleich innerhalb der kritischen Services durchführen. Delegieren Sie die Ausgleichsarbeit an den Client, indem Sie ihn anweisen, sich direkt mit den relevanten Servern zu verbinden (offensichtlich müssen die Server die Berechtigungen überprüfen). Machen Sie es sich so einfach wie möglich, dokumentieren Sie die Verantwortlichkeiten der verschiedenen Dienste und Server und aktivieren Sie die Debug-Ausgabe.

PS: Einige dieser Techniken können verwendet werden, um die Zuverlässigkeit zu verbessern. Und Sie sollten dies berücksichtigen, da die Verwendung vieler Server ein viel höheres Risiko mit sich bringt, dass Dinge kaputt gehen. nicht nur in der Software, sondern auch auf Hardwareebene.

Hendrik Brummermann
quelle
Aber wie machen Sie diese Interprozesskommunikation wirklich? Welche Art von IPC sollte verwendet werden?
Majidarif
10

Im Allgemeinen ist die Welt in eine Reihe kleinerer Regionen unterteilt. Jede dieser Regionen ist normalerweise ein unabhängiger Serverprozess (WoWs Weltserver oder Eves Sol-Knoten) und kann auf einer beliebigen Anzahl von Computern ausgeführt werden. In einigen Spielen gibt es explizite Türen zwischen Karten (Eve, STO, Guild Wars), während andere versuchen, dies mehr zu maskieren (WAR, Free Realms). Diejenigen, die sich für den nahtloseren Ansatz entscheiden, erkennen im Allgemeinen, wenn Sie sich der Grenze zwischen zwei Servern nähern und der Prozess eine Übergabe aushandelt. Der beste Ort, um wahrscheinlich nach einer Beschreibung dafür zu suchen, ist die Art und Weise, wie Mobilfunkmasten Handoffs von sich bewegenden Mobilteilen ausführen. Wenn die Last einer einzelnen Karte (Jita, Ironforge, Earth Space Dock) sehr groß wird, können Sie manchmal einzelne Funktionen auf andere Server (AI, bestimmte Teile der Spielerverwaltung), aber dies muss entweder von Anfang an eingebaut werden oder würde eine ernsthafte Nachrüstung erfordern. Es ist fast immer kostengünstiger, einfach eine bessere Hardware für diese wenigen Karten zu kaufen.

coderanger
quelle
9

Ich glaube, dass MMOs häufig verlangen, dass die Verarbeitung für einen einzelnen Shard oder Realm über mehrere Server erfolgen kann, um die Auslastung zu verringern. Ich bin gespannt, wie dies unter Beibehaltung einer einheitlichen, konsistenten Welt geschehen kann, in der alle Spieler und alle NPCs interagieren können.

Es ist wahrscheinlich nicht so verbreitet, wie Sie denken; Zumindest nicht, wenn Sie glauben, dass eine nahtlose Welt von mehreren Servern gleichzeitig verwaltet wird.

Abgesehen von völlig getrennten Scherben gibt es zwei Richtungen, in die Sie ein Online-Spiel aufteilen können, die als "horizontal" und "vertikal" betrachtet werden können:

  • Teilen Sie das Spiel in verschiedene geografische Gebiete auf. Alle Funktionen für ein bestimmtes geografisches Gebiet werden von einem Server ausgeführt, und es gibt keine wirkliche Interaktion zwischen ihnen. (Beachten Sie, dass es nicht unbedingt nur eine Zone pro Server gibt - ein Server kann möglicherweise mehrere Zonen gleichzeitig verwalten, und Zonen können möglicherweise zwischen Servern übertragen werden, um sich ändernde Lasten zu bewältigen.)
  • Teilen Sie das Spiel in verschiedene Arten von Diensten auf - z. Login / Autorisierung, Spielregeln und -physik, Chat + Auktionen, Persistenz usw. Jeder dieser Dienste kann von einem anderen Server verwaltet werden. Die Antwort von nhnb hat andere potenzielle Dienste aufgezählt, in die ein Entwickler sein Spiel unterteilen kann.

Offensichtlich sind diese Ansätze orthogonal und Sie können beide kombinieren. Tatsächlich ist es fast zwingend erforderlich, einen separaten Datenbankserver zu haben. Dies ist häufig der Fall, wenn Anmeldedaten / Authentifizierung vom Spiel auf einen anderen Computer übertragen werden sollen, und wird immer häufiger auch bei der Auslagerung von Chats und anderer nicht kritischer Kommunikation verwendet, unabhängig von Ihrer Spielewelt ist aufgeteilt.

Aber im Großen und Ganzen vermeiden die meisten Spiele bei geografischer Unterteilung, dass Sie über diese Grenzen hinweg interagieren, da es schwierig ist, gute Ergebnisse zu erzielen. Stattdessen greifen sie auf andere Arten zurück, um den Eindruck zu erwecken, dass Sie sich immer noch im selben Shard und auf demselben Server befinden, obwohl Sie es eigentlich nicht sind. z.B. - Laden von Bildschirmen oder anderen Animationen, die einen Serverwechsel beim Übergang zwischen Zonen oder von einem Kontinent auf einen anderen verdecken. - Separate Dungeon- oder Raid-Instanzen, die von allen anderen isoliert sind. Diese sind wie ein Shard innerhalb eines Shards und können problemlos auf einem separaten Server ausgeführt werden, um den Lastenausgleich zu erleichtern.

Ich kann nicht mit Autorität über WoW sprechen, aber ich würde vermuten, dass sie fast alle der oben genannten Dinge tun: Instanzen, getrennte geografische Gebiete, die nicht miteinander interagieren können, verbunden durch Portale irgendeiner Art, getrennte Back-End- und Authentifizierungsserver. Ich habe gehört, dass in WoW-Bereichen zwischen 1000 und 10000 Spieler gleichzeitig online sind, was mit den oben genannten Schemata leicht zu handhaben ist.

Nehmen wir jedoch an, Sie haben eine einzige riesige Welt und müssen den Spielern einen Server erlauben, mit den Spielern auf einem benachbarten Server zu interagieren. Dies ist theoretisch einfach zu bewerkstelligen: Zuerst müssen Server zusammenarbeiten, um Details von Objekten entlang der Grenzen auszutauschen (sodass ein Objekt auf einem Server möglicherweise eine Proxy-Darstellung auf einem anderen hat), und dann einfach Ihre gesamte Logik auf Nachrichtenübermittlung mit ändern Nachrichten werden bei Bedarf von einem Proxy zurück an die autorisierende Quelle geleitet. Nachrichten können zwischen Servern oder innerhalb eines Servers ziemlich transparent übertragen werden, sodass ein Ansatz für alle Systeme geeignet ist.

Das Problem hierbei ist, dass zuvor einfache Logik beim Übersetzen in Nachrichten sehr komplex werden kann - z. Ein 2-Spieler-Handel, der sicher und atomar stattfinden kann, wenn sich beide Spieler auf einem Server befinden, wird zu einem längeren Prozess, wenn Nachrichten hin und her gesendet, bei jedem Versand überprüft und Sicherheitsvorkehrungen getroffen werden müssen, um sicherzustellen, dass ein Spieler nicht ausnutzen kann die andere durch Ändern des Handels, während eine Nachricht unterwegs ist. Sie können nicht einmal davon ausgehen, dass der andere Spieler zum Zeitpunkt des Eingangs der Nachricht noch vorhanden ist (da er möglicherweise stirbt, sich abmeldet usw.), sodass der Code sehr komplex wird. Dies gilt für nahezu jedes System, in dem zwei oder mehr Einheiten interagieren oder zusammenarbeiten können - Handel, Kampf, Gruppierung, Auktionen, Beutetausch, Training usw.

Diese Probleme sind nicht unüberwindbar, aber für die meisten Spiele ist es zu schwierig, sie zu versuchen, wenn Sie die Last auf andere Weise teilen und Ihre gesamte Spielelogik auf einem Server speichern können. Also gehen fast alle aktuellen Spiele diesen Weg.

Kylotan
quelle
3

Es gibt viele Methoden zum Lastenausgleich eines MMO-Servers, da eine Vielzahl von Daten verarbeitet werden muss. Ich bevorzuge die Prozess-Bin-Tree-Methode.

Ein globaler Server leitet Benutzerverbindungen an einen Prozessbehälter weiter, der mehrere Benutzer gleichzeitig verarbeiten kann. Die Prozessfächer erledigen die gesamte komplexe Verarbeitung und antworten dem globalen Server nur mit Daten, die global relevant sind, z. B. globaler Chat und Positionierung. Diese Methode gleicht viel besser als Regionsserver aus, da Regionen in der Population stark variieren können, während die Benutzerverarbeitung insgesamt so unterschiedlich ist, dass sie sich zum größten Teil von selbst ausgleichen sollte.

Führen Sie einfach einen grundlegenden Lastenausgleich über den globalen Server durch. Wenn ein Prozessbehälter eine bestimmte Speicher- / CPU-Auslastung erreicht, starten Sie einen neuen Prozessbehälter-Server.

Stephen Belanger
quelle
Wie teilt man Daten, die zwischen Prozessablagen geteilt werden, zum Beispiel einen Kampf zwischen zwei Benutzern in verschiedenen Prozessablagen? Wie stellen Sie die Reihenfolge der Ereignisse sicher? Ein getöteter Spieler kann also keinen Angriff mehr ausführen, selbst wenn der Behälter, der ihn tötet, langsamer ist als der Behälter, der den Angriff ausführt. Besteht das Risiko, dass der Dispositionsaufwand auf dem globalen Server zu hoch wird? Das Proxy-Modell für die Benutzerverbindungen kann zu Einschränkungen des Betriebssystems auf dem Netzwerkstapel führen.
Hendrik Brummermann
Dieses Modell funktioniert ziemlich gut in Informationssystemen, in denen die meisten Transaktionen isoliert sind. Ich meine, sie arbeiten normalerweise nicht mit denselben Daten, und in den seltenen Fällen wird das Sperren oder Zurücksetzen verwendet. In Spielen, in denen Kämpfe mit mehreren Spielern und / oder Kreaturen ausgetragen werden und die Auswirkung von Angriffen von den Attributen sowohl des Angreifers als auch des Verteidigers beeinflusst wird, kann dieser Ansatz schwierig sein.
Hendrik Brummermann 30.11.10
Sie können entweder den einfachen Weg gehen und Mehrbenutzerinteraktionen als global relevant erachten oder eine einfache Methode erstellen, mit der sich Prozessfächer gegenseitig kennen und kommunizieren. Jeder Prozessbehälter sollte in der Lage sein, ungefähr zehntausend Benutzer gleichzeitig zu bearbeiten, damit die Zustandskommunikation zwischen Benutzern kein allzu großes Problem darstellt. Die Regionsmethode ist etwas einfacher, aber nicht so ausgewogen und kann leicht zum Absturz gebracht werden, wenn zu viele Benutzer dieselbe Region betreten. In einem MMORPG mit einer großen Benutzerbasis ist es sehr wichtig, die Last gleichmäßig zu verteilen.
Stephen Belanger
Ich würde gerne "eine einfache Methode" für 2 Prozessfächer kennen, um ein System wie den Kampf aushandeln zu können. Das Problem ist nicht die niedrige Kommunikationsstufe, sondern die Tatsache, dass typische Gameplay-Algorithmen bei verteilten Teilnehmern sehr kompliziert werden.
Kylotan
In meiner Implementierung verwaltet mein globaler Server eine Liste aller verbundenen Clients und verfolgt, mit welchem ​​Prozessbehälter sie verbunden sind. Wenn ein Prozessbehälter auf einen anderen Benutzer zugreifen muss, überprüft er zuerst seine eigene Benutzerliste. Wenn dies fehlschlägt, wird die globale Liste überprüft und festgestellt, mit welchem ​​Prozessbereich der andere Benutzer verbunden ist. Die Prozessfächer stellen dann eine direkte Verbindung her, um Benutzerzustände freizugeben, während die einheitliche Verarbeitung ausgeführt wird.
Stephen Belanger