Ich möchte die SQL-Datenbank in meiner server.exe verwenden.
Sagen wir 1000 Benutzer online. Und die Spieler ändern ihre Daten, wenn sie spielen. Und Server müssen diese Updates speichern.
Aber wie ?
Ich denke da in zwei Richtungen:
1) Der Server speichert zur Laufzeit im RAM und der Server schreibt irgendwann oder stündlich Daten (Aktualisierung) von RAM in die SQL-Datenbank. Wenn der Strom ausfällt oder der Server ausfällt, werden keine Updates gespeichert. Natürlich möchte ich keine Updates verlieren.
2) Der Server speichert die Aktualisierungen zur Laufzeit in der Datenbank. aber was passiert mit der Geschwindigkeit? Ich dachte an eine Methode. Ich werde Sie unten mit Bild zeigen. Kann ich mit dieser Methode genug Geschwindigkeit für 1000 Online-Spieler erreichen?
quelle
Antworten:
Die meisten MMOs (oder Projekte mit ähnlicher Architektur), an denen ich gearbeitet habe oder die ich kenne, verwenden die erste Methode: Die Spielserver arbeiten hauptsächlich mit dem RAM auf den Computern, auf denen die Serverprozesse ausgeführt werden, und serialisieren die relevanten Spieldaten nur regelmäßig in eine SQL-Datenbank zur Archivierung (falls überhaupt eine verwendet wird).
Die Probleme, die Sie aufgrund eines Stromausfalls feststellen, sind gültig, aber weniger wahrscheinlich als Probleme wie Abstürze im Prozess (Zuverlässigkeit der Betriebszeit ist im Allgemeinen eines der Dinge, für die Sie das Rechenzentrum bezahlen würden). Aber dennoch. Sie verringern diese Probleme, indem Sie beispielsweise das Sicherungsintervall optimieren (ein Fehler kostet höchstens ein paar Minuten Fortschritt), die Sicherungswarteschlangen auf mehrere Computer verteilen, die zu sichernde Datenmenge aggressiv einschränken und eine neu startbare Sicherung implementieren Warteschlangen.
Im Allgemeinen ist die Verwendung des SQL-Servers als Hauptspeicher unangenehm langsam (und umständlich). Ich sehe dort nicht genug Details in Ihrem Vorschlag, um sicher sagen zu können, ob es nur für ungefähr 1000 Spieler funktionieren würde - es wäre wahrscheinlich in Ordnung. Aber ich glaube nicht, dass Sie es aggressiv skalierbar machen können.
Außerdem löst es das Problem nicht. Ein Stromausfall während des Speichervorgangs wird weiterhin Daten verlieren oder beschädigen, es sei denn, Sie implementieren die gleiche Art von neu startbarer Speicherwarteschlange (was selbst dann die Wahrscheinlichkeit eines katastrophalen Datenverlusts nur erheblich verringert, aber nicht verhindert). .
Ich würde empfehlen, dass Sie mit dem ersten Ansatz gehen.
quelle
1000 Spieler können ein Problem sein oder auch nicht. Dies hängt davon ab, wie oft Sie die Datenbank aktualisieren müssen. Es gibt jedoch eine einfache Lösung: Platzieren Sie die Datenbank auf einem eigenen Server.
Ich habe einen Blick darauf geworfen, wie das Datenbanksystem in einem Spiel funktioniert, das die Leute als MMO-Lite bezeichnen würden - was ich nicht preisgeben werde -, aber ich kann sagen, dass es durchweg mehr als 1000 Spieler hat. Dies ist die Zusammenfassung:
In diesem Fall ist die Verwendung einer dokumentbasierten Datenbank eine gute Idee für die Leistung. Es ist gut, auf die Daten zuzugreifen, auch wenn es schlecht ist, um Verknüpfungen und Aggregationen durchzuführen ... aber sie werden das nicht mit den Daten tun, die sich dort befinden.
Auf der anderen Seite, wenn sie so etwas wie das Ändern eines Objekts mit einem anderen Objekt für alle tun müssen, und wenn ein Hintergrundskript ausgeführt werden muss, das zeichenweise abläuft und einzeln aktualisiert wird, dauert es merklich lange.
Die Daten des Charakters sind sowohl auf dem Client als auch auf dem Server vorhanden, und das System ist so ausgelegt, dass sie synchron bleiben und auf beiden Seiten dieselben Vorgänge ausführen.
Wenn nun ein Spieler eine Transaktion mit dem System durchführt - zum Beispiel einen Gegenstand über einen NPC oder Ähnliches gegen einen anderen austauschen - hat dies folgende Stufen:
Anmerkungen :
Trades zwischen Spielern werden ähnlich gehandhabt, mit zusätzlichen Regeln, um zu verhindern, dass Spieler andere Spieler betrügen, und zusätzlicher Rückverfolgbarkeit, falls eine Transaktion rückgängig gemacht werden muss. Ich habe gehört, dass es spezielle Protokolle aller Transaktionen gibt, die für einige Zeit aufbewahrt werden (um Probleme zu lösen, wenn sich jemand beschwert). Ich weiß nicht mehr, wie dieser Teil funktioniert.
Manchmal geht etwas schief, dies hat zwei mögliche Folgen:
In beiden Fällen ist der Client über den Fehler informiert und protokolliert ihn zusammen mit allem, was der Spieler getan hat. Die Client-Seite wird ständig protokolliert. Wenn beim Abmelden ein Fehler aufgetreten ist, sendet der Client die Protokolle an den Server.
Dieses Spiel verwendet nicht die üblichen täglichen oder wöchentlichen Wartungsunterbrechungen, die die meisten MMORPGs haben. Diese geplante Wartung wird häufig zum Zurücksetzen von Zählern, Zeitgebern und Ausführen von Datenbankprozeduren verwendet. Sie bieten auch die Möglichkeit, Serverversionen gegen ein Update auszutauschen.
quelle
x:10,y:10,z:10
Anx:11,y:11,z:11
, sollte dies sofort in der Datenbank gespeichert werden? Wenn der Spieler weiterläuft, bedeutet dies, dass wir seine aktuelle Position alle 1 Sek. oder weniger speichern. Wenn es Tausende von Spielern gibt, sind das Millionen von Abfragen an die Datenbank pro Sekunde. Funktioniert das so?Beide Ansätze werden mit MMORPGs verwendet. Es scheint die beliebteste Option zu sein, alles im Speicher zu belassen und regelmäßig zu überprüfen, ob es auf die Festplatte verweist, zumindest für ältere Spiele. Es hat den Vorteil, dass es relativ einfach zu implementieren und relativ gut zu skalieren ist. Die Zuverlässigkeit liegt jedoch ganz bei den Entwicklern. SQL-Datenbanken bieten ACID-Eigenschaften , die die Zuverlässigkeit vereinfachen, insgesamt aber schwieriger zu implementieren sind und Probleme bei der Skalierung verursachen können.
EVE Online ist ein Beispiel für ein MMO, in dem alles in einer SQL-Datenbank gespeichert ist. Meiner Meinung nach lag der Höchststand bei etwa 60.000 gleichzeitigen Benutzern, und im Laufe der Jahre musste teure Hardware für die Datenbankserver bereitgestellt werden, um mit der Last Schritt zu halten. EVE speichert jedoch viel mehr Daten pro Benutzer als die meisten MMORPGs und hat viel häufigere und vielfältigere Transaktionen. Die ACID-Eigenschaften der Datenbank ermöglichen es, die gesamte massive und komplizierte Datenbank immer in einem konsistenten Zustand zu halten.
Betrachten Sie zum Beispiel den Fall, dass jemand einem anderen Spieler einen Gegenstand gibt. Die Datenbank von EVE garantiert, dass der Gegenstand auch bei einem Absturz oder Stromausfall nur im Inventar eines Spielers landet. Das heißt, die Datenbanktransaktion, die den Gegenstand aus dem Inventar eines Spielers entfernt und zum Inventar des anderen Spielers hinzufügt, ist atomar. Die Transaktion wird entweder vollständig abgeschlossen oder überhaupt nicht ausgeführt. Sie können nicht in einem Zustand enden, in dem der Gegenstand weder im Inventar der Spieler noch in beiden vorhanden ist.
Ein MMORPG, das Spielerdaten im Speicher hält und diese regelmäßig überprüft, muss diese Atomizität selbst implementieren. Eine Möglichkeit, dies zu tun, besteht darin, die Daten aller Spieler gleichzeitig zu überprüfen und sicherzustellen, dass der neue Prüfpunkt vollständig auf die Festplatte übertragen wird, bevor er als der letzte Prüfpunkt betrachtet wird. Das Spiel müsste auch sicherstellen, dass sich die Spielerdaten nicht ändern können, während sie überprüft werden. Bei einer großen Anzahl aktiver Spieler wird die Herausforderung all dies tun, ohne eine Verzögerung zu verursachen, die die Spieler bemerken würden.
Unterschätzen Sie nicht, wie wichtig Konsistenz ist. Wenn du dein Spiel entwickelst, wird es sehr abstürzen. Sie möchten nicht herausfinden müssen, warum Elemente verschwinden und / oder dupliziert werden, und nicht, wenn das Problem darin besteht, dass ein nicht verwandter Fehler das Spiel zu einem schlechten Zeitpunkt zum Absturz bringt. Wenn Ihr Spiel live geht, stürzt es außerdem weitaus mehr ab, als Sie erwarten. Ihr Server, der unter Testbedingungen einwandfrei funktionierte, wird plötzlich zahlreiche Fehler unter Volllast aufdecken und Spieler tun, was Sie nicht erwartet haben.
Beachten Sie, dass die meisten MMORPGs SQL-Datenbanken für kontobezogene Informationen verwenden, auch wenn sie keine tatsächlichen Spieldaten enthalten. Noch wichtiger als das Beibehalten des Spielstatus ist das Beibehalten des Abrechnungsstatus. Das Schlimmste daran, dass die Spieldatenbank beschädigt wird, ist, dass Sie die Datenbank aus einer täglichen Sicherung wiederherstellen müssen. Das Schlimmste daran, dass die Kontodatenbank beschädigt wird, ist, dass Sie wegen aller Rückbuchungen bankrott gehen.
Für Ihr Projekt können Sie wahrscheinlich beide Wege gehen. Mit 1000 gleichzeitigen Benutzern werden die Grenzen dessen, was ein SQL-Server heutzutage auf einem Standard-PC kann, wahrscheinlich nicht überschritten, aber vieles wird von der Art der Transaktionen abhängen. Wenn Sie mit SQL und dem Entwurf relationaler Datenbanken vertraut sind, kann dies für Sie hilfreich sein. Sie möchten die Transaktionen so weit wie möglich minimieren. Bei aktuellen Hitpoints des Spielers möchten Sie diese möglicherweise nur regelmäßig in der Datenbank speichern, da Statistiken wie diese nicht unbedingt konsistent sein müssen. (Im PvP-Spiel könnten sie jedoch ...) Speichern Sie keine Objekte wie Monster-HP in der Datenbank, da in den meisten Spielen nur spielerbezogene Daten persistent sind.
Wenn Sie jedoch kein SQL-Assistent sind, ist es möglicherweise einfacher, alle Daten im Arbeitsspeicher zu behalten, damit Sie zuverlässig arbeiten können. SQL-Datenbanken vereinfachen die Konsistenz und Zuverlässigkeit, sind jedoch nicht automatisch. Eine schlecht gestaltete Datenbank kann schlecht funktionieren und zu Inkonsistenzen führen. Transaktionen werden nicht atomar sein, es sei denn, Sie machen sie so. Wenn Sie parametrisierte Anweisungen nicht religiös verwenden, sind Sie SQL-Injection-Angriffen ausgesetzt.
quelle
Verschiedene Spiele speichern Dinge auf unterschiedliche Weise. Oft schaffen Spielefirmen einen Weg, dies zu tun, und die meisten ihrer Spiele verwenden den gleichen Weg. Natürlich verwenden verschiedene Studios oft unterschiedliche Methoden. SQL wird sicherlich für Spiele verwendet, zB CCP (EVE) hat (oder hatte zumindest) ein Netzwerk von SQL-Servern, ich bin nicht sicher, wie sie es jetzt tun. Andere verwenden einfach viele Dateien.
Beginnen Sie vielleicht damit, einen agnostischen "Datenvermittlungsmechanismus" zu erstellen, um verschiedene Spieldaten-Transaktionen abzuwickeln? Da Sie sowieso nur testen, sollten Sie einen Mechanismus erstellen, mit dem Sie sich vom Standpunkt des Spiels aus nicht allzu sehr um den Speicher kümmern müssen. Konzentrieren Sie sich also darauf, wie Sie in der Host-Anwendung damit umgehen.
Persönlich denke ich, dass es ein großer Vorteil wäre, wenn Sie den eigentlichen Shop wechseln könnten, ohne das Spiel und den Broker selbst neu schreiben zu müssen. Wechseln Sie einfach zu einem anderen Modul mit derselben Schnittstelle, mit dem der Broker kommunizieren kann.
Das Speichern von Daten an sich ist an sich wahrscheinlich kein Problem. Ein effizienter Versand von Daten zwischen dem Host und allen Kunden zu / von diesem Geschäft könnte schwieriger sein. Versende ich den gesamten Player-Datensatz oder teile ich ihn in Teile auf, nach welcher Granularität ich partitioniere usw. Welcher ist in welcher Situation ressourcenintensiver usw.
Ein Format zum Versenden der Daten könnte XML sein. Auf diese Weise können Sie dynamischer sein, wie Sie es aufteilen können. Ein Zeichen gegen mehrere Zeichen oder ein Element gegen eine Sammlung von Elementen usw. Sie können dann entweder das XML als XML (in SQL) "speichern" und / oder SQL veranlassen, es in einer transaktionaleren Art und Weise von XML zu verteilen Wie sollen die Daten tatsächlich gespeichert werden?
Ein anderer Weg ist der binäre Weg, der in Bezug auf den Versand effizienter ist, in anderen Situationen jedoch höhere Kosten verursachen kann.
Bei 1.000 Clients können Sie zunächst 10 MB pro Client speichern und nur 10 GB effektiven Arbeitsspeicher verwenden. Fügen Sie ein paar Systemverwaltungs-Arbeitsspeicher hinzu, um diese Daten zu verwalten, beispielsweise ein oder zwei weitere GB. Sie könnten das im RAM auf dem Host bereits in Datenstruktur einsatzbereit halten. Und laden / speichern Sie dynamisch, abhängig davon, wer online ist, in verschiedenen Frequenzen, abhängig von der Aktivität usw.
Sie können die Informationen jedes Kunden sogar in einer separaten Datei speichern und so weiter.
quelle
Lasse * Online * -Spieler im RAM und schiebe sie auf eine Datenbank (SQLite? MySQL?), Wenn sie sich abmelden. Wenn du dir Sorgen machst, dass die E / A während des Abmeldevorgangs blockiert, gib jedem Abmeldevorgang einen eigenen Thread, mache das nicht im Haupt- / Spiel-Thread (eigentlich habe ich für jeden Online-Spieler einen eigenen Player-Thread, das hat den Netzwerkcode so viel einfacher gemacht) als die asynchrone Netzwerk io Ansatz zu tun)
quelle