mmorpgはどのようにデータを保存しますか?


22

server.exeでSQLデータベースを使用したい。

1000人のユーザーをオンラインで言うことができます。プレイヤーはプレイするときにデータを変更します。サーバーはこれらの更新を保存する必要があります。

しかし、どのように?

私は2つの方法があると思います:

1)サーバーは実行時にRAMに保存し、いつか1時間ごとにサーバーがRAMからSQLデータベースにデータを書き込みます(更新)。ただし、電力が供給されるか、何らかの理由でサーバーがシャットダウンすると、更新は保存されません。もちろん、更新を失いたくありません。

2)サーバーは実行時にデータベースに更新を保存します。しかし、速度はどうなりますか?方法を考えました。以下に画像を示します。この方法で1000人のオンラインプレイヤーに十分な速度を得ることができますか? ここに画像の説明を入力してください


11
ベンチマークを実行しましたか?データベース操作がゲームの問題になると思われる理由は何ですか?
コンガスボンガス

3
ゲームの状態が実際にリレーショナルである場合は?SQLデータベースが必要ですか?
ハーミングモニカの停止

6
ハッシュを使用してパスワードを処理する方法もお読みください。または、少なくともパスワードがプレーンテキストとして保存されていることをユーザーに通知し、別の安全なパスワードを使用しないようにします。
TomTsagk

24
補足として、商用 MMO を構築する場合で、このような質問をしている場合は、おそらくより小さなものから始める必要があります。MMOは、それを正しく行うことはもちろんのこと、非常に難しいことであり、ビジネスの観点からはそれほど優れていません。これが単なる個人的なことで、プレイヤー数を増やしたい場合は、64人のプレイヤーのようなものから始めて、上に向かって進みます。「完璧な」アーキテクチャを経験なしでゼロから設計しようとするよりもはるかに簡単です。参照してくださいこれを
ファンドモニカの訴訟

1
ストレージに依存しない一般的なAPIを作成できます。次に、遅延ストレージ用にデータをRAMにキャッシュするアダプターを作成します。または、SQL DBでフラッシュする前に、一時ファイルにデータをキャッシュするアダプターを作成できます。そうすれば、キャッシュのオンとオフを切り替えて、どちらが最適かを見つけることができます。アーキテクチャが適切に構築されていれば、余分なコードを書く必要はありません。
0xC0DEGURU

回答:


37

私が取り組んだほとんどのMMO(または同様のアーキテクチャを使用するプロジェクト)は、最初の方法を使用したことを知っています:ゲームサーバーは、サーバープロセスを実行しているマシンのRAMで主に動作し、関連するゲームデータを定期的にSQLデータベースにシリアル化しますアーカイブ用(使用されている場合)。

停電に関して注意する問題は有効ですが、プロセスのクラッシュなどの問題よりも起こりにくいです(通常、稼働時間の信頼性は、データセンターに支払うものの1つです)。それでも。保存間隔の調整(障害が発生するのはせいぜい数分しかかからない)、保存キューを複数のマシンに分散させる、保存する必要のあるデータ量を積極的にスコープする、再起動可能な保存を実装するなどの方法でこれらの問題を軽減しますキュー。

一般的に、SQLサーバー自体をメインメモリとして使用すると、不快なほど遅くなります(面倒です)。あなたの提案には十分な詳細がありませんが、約1000人のプレイヤーだけでうまくいくかどうかを確実に言うことができます。おそらく大丈夫でしょう。しかし、積極的にスケーラブルにできるとは思いません。

さらに、それは問題を解決しません。保存プロセス中の電源障害は、同じ種類の再起動可能な保存キューを実装する作業を行わない限り、データを損失または破損します(それでも、壊滅的なデータ損失の可能性を大幅に減らすだけで、それを防ぎません) 。

最初のアプローチをお勧めします。


10
「保存間隔の調整」に関して、私が最後に取り組んだMMOでは、アクティブなプレイヤーの数に基づいて保存間隔が設定されていました。目立ったボトルネックなしに1秒あたりXプレーヤーのデータを保存できることはわかっていたので、1秒あたりXプレーヤーを少しずつ節約することができました。通常は、忙しい日に2分ごとに各プレーヤーのセーブになり、遅い時間には1分に2回セーブされます。
平均値

4
「再起動可能な保存キュー」は、多くのファイルシステムやデータベースエンジンで実装されているように、ジャーナルのように聞こえますか?
悲しみ

6
これらの問題は、のMMO、あるいはビデオゲームに固有のものではありませんすべてで。存在するほぼすべてのORMは、何らかのキャッシュ/バッチ処理メカニズムを提供します。独自のソリューションを展開する必要はありません。
BlueRaja-ダニー・プルフホイフト

3
特定の間隔でディスクに保存することになった場合は、人々がまれなドロップ/ダイ/などを取得したときにすぐに保存できるシステムを設計することをお勧めします。そうすれば、サーバーがクラッシュしたり、何かがあったとしても、大きなことを成し遂げた人々は動揺しません。
ジョン

5
@Jon、そしてあなたは人々がオブジェクトを複製できるという問題に出くわします。理想的には、ゲームの状態全体を単一のトランザクションとして定期的に保存します。ピース単位で保存を開始すると、クラッシュによりデータの一貫性が失われる可能性があります。必要に応じてクラッシュをトリガーしたり、クラッシュがいつ発生する可能性があるかを予測したりできるプレーヤーは、これを活用して有利にすることができます。
マーク

15

1000プレーヤーが問題になる場合とそうでない場合があります。データベースを更新する必要がある頻度によって異なります。ただし、簡単な解決策があります。データベースを独自のサーバーに配置します。


データベースシステムがMMO-Liteと呼ばれるゲームをどのように機能させるかを覗きましたが(これは公開しません)、1000人以上のプレイヤーがいることを一貫して確認できます。これは要約です。

  • 彼らは、プライベートキャラクター情報(在庫、装備など)にドキュメントベースの「No-SQL」データベースを使用しています。
  • 彼らはめったに更新されない公開キャラクター情報(名前、実績など)と統計のために、より伝統的なリレーショナルデータベースを使用します。

この場合、ドキュメントベースのデータベースを使用することがパフォーマンスの良いアイデアであることがわかりました。結合や集計を行うのは良くありませんが、データにアクセスするのには適していますが、そこにあるデータに対してはそうしません。

一方、すべての人のためにオブジェクトを別のオブジェクトに変更するような何かをする必要がある場合、文字ごとに行ってそれらを1つずつ更新するバックグラウンドスクリプトを実行する必要があるため、かなりの時間がかかります。


キャラクターのデータはクライアントとサーバーの両方に存在し、システムはそれらを同期させ、両側で同じ操作を行うように設計されています。

現在、プレイヤーがシステムとトランザクションを行う場合-たとえば、NPCなどを介してアイテムを交換する場合-これには、次の段階があります。

  • クライアントは、操作が有効かどうかを確認します
  • クライアントは操作をサーバーに送信します(非同期操作)
  • クライアントはRAMでモデルを更新します
  • サーバーは、操作が有効かどうかを確認します
  • サーバーはRAMでモデルを更新します
  • サーバーはデータベースを更新します(非同期操作)
  • サーバーは、変更が発生したことをクライアントに伝えます

  • データベースの更新は、非同期ですが、すぐに行われます。何らかの理由でゲームサーバーがダウンした場合でも、多くは失われません。
  • データベースを独自のサーバーに配置することで、パフォーマンスの低下は大したことではありません。

プレイヤー間の取引も同様に処理され、プレイヤーが他のプレイヤーを詐欺することを防ぐための追加のルールと、取引を取り消す必要がある場合の追加のトレーサビリティがあります。誰かが不平を言ったときに問題を解決するために)しばらく保持されるすべてのトランザクションの特別なログがあると聞きましたが、その部分がどのように機能するのかはわかりません。


時々何かがうまくいかない場合、これには2つの結果があります:

  • エラーがすぐに発生した場合、サーバーはクライアントに通知し、クライアントは操作を元に戻します(プレーヤーは元に戻された操作を確認します)。
  • UIには、プレーヤーにはアイテムがありますが、サーバーは同意しません。ユーザーがそれを使用しようとすると、サーバーに問い合わせて失敗し、偽のオブジェクトを使用できなくします。在庫が再ロードされると、偽オブジェクトはなくなります。これは、モデルを同期する機会として使用されます。

いずれの場合でも、クライアントはエラーを認識しており、プレーヤーが行っていたすべてのエラーとともにログに記録します。クライアント側のロギングは常に行われています。次に、ログアウト時にエラーが発生した場合、クライアントはログをサーバーに送信します。


このゲームでは、ほとんどのMMORPGにある従来の毎日または毎週のメンテナンスダウンタイムは使用しません。その定期メンテナンスは、カウンター、タイマーのリセット、データベースプロシージャの実行によく使用されます。また、更新のためにサーバーのバージョンを交換する機会でもあります。


おかげで、たとえばプレーヤーの動きについてはどうでしょう。プレーヤーが現在の位置から移動する場合:x:10,y:10,z:10x:11,y:11,z:11、これをすぐにデータベースに保存する必要がありますか?プレーヤーが走り続けている場合、これは現在の位置を1秒以下ごとに保存することを意味し、数千のプレーヤーがいる場合、毎秒数百万のDBへのクエリになります。これはどのように機能しますか?
dwix

2
プレイヤーの位置がデータベースに保存されることはほとんどありません。メニューを開く、キャンプファイヤーを開始する、休むなどの特別な機会にのみそれが必要になります。ゲームによっては、その詳細さえ保存されません。一部のゲームでは、常に最寄りの町などでスポーンさせるため、位置を保存する手間も省けます。しかし、それは意見に基づいています。
ニコ

1
@dwixで説明したゲームの場合、プレーヤーの位置は保存されません。ログアウトしてログインした場合、またはサーバーがダウンした場合、プレーヤーは安全な既知の位置に戻されます(編集:それはプライベートインスタンスであり、「ハウス」であれば、誰でも同じです)。ただし、一部のゲームでは、偶発的な切断であっても、プレーヤーの正確な位置を維持します。それを行うための通常のアプローチは、その情報をあまり頻繁に保存しないことです。とにかく、サーバーがデータベースで待機していることはしません。
Theraot

1
@dwixアバターの位置について話すとき、あなたは本当に歴史的な価値を気にしませんよね?さて、データベースがボトルネックの場合は、データを調整します。各サーバーティックを保存する代わりに、保存頻度を減らします。これは、データベースが最新の値を持たないことを意味しますが、パフォーマンスにそれほど影響を与えません。その間、サーバーは引き続きRAMに更新値を保持し、それが動作するものです。補遺:正直なところ、私はポジションを保存しないようアドバイスしますが、いくつかのゲームはそうします。
Theraot


7

両方のアプローチは、MMORPGで使用されます。少なくとも古いゲームでは、すべてをメモリに保持し、ディスクを指すように定期的にチェックすることが最も一般的なオプションのようです。実装が非常に簡単で、スケーリングが非常に優れているという利点がありますが、信頼性を高めることは開発者次第です。SQLデータベースはACIDプロパティを提供します、信頼性を容易にをが、実装が全体的に複雑になり、スケーリングに問題が生じる可能性があります。

EVE Onlineは、すべてがSQLデータベースに保存されるMMOの例です。同時ユーザー数が約60,000でピークに達し、負荷に対応するために、長年にわたってデータベースサーバーに高価なハードウェアを捧げなければならなかったと思います。ただし、EVEは、ほとんどのMMORPGよりも多くのデータをユーザーごとに保存し、より頻繁で多様なトランザクションを保持しています。データベースのACIDプロパティにより、大規模で複雑なデータベース全体を常に一貫した状態に保つことができます。

たとえば、誰かが他のプレイヤーにアイテムを渡す場合を考えてみましょう。EVEのデータベースは、クラッシュまたは電源障害が発生した場合でも、アイテムが1人のプレイヤーのインベントリのみに収まることを保証します。つまり、あるプレイヤーのインベントリからアイテムを削除し、他のプレイヤーのインベントリに追加するデータベーストランザクションはアトミックです。トランザクションは完全に完了するか、まったく発生しません。アイテムがどちらのプレイヤーのインベントリにも両方にも存在しない状態になることはありません。

プレイヤーデータをメモリに保持し、定期的にチェックポイントを保持するMMORPGは、この原子性自体を実装する必要があります。これを行う1つの方法は、すべてのプレーヤーのデータを同時にチェックポイントし、最新のチェックポイントと見なされる前に新しいチェックポイントがディスクに完全にコミットされるようにすることです。また、ゲームでは、チェックポイントが設定されている間はプレーヤーデータが変更されないようにする必要があります。アクティブなプレイヤーが大量にいると、プレイヤーが気付くほどの遅延を引き起こすことなく、このすべてを行うことが課題になります。

一貫性の重要性を過小評価しないでください。ゲームを開発していると、多くのクラッシュが発生します。問題が無関係のバグが原因でゲームがクラッシュした場合ではなく、アイテムが消えたり複製されたりする理由を追跡する必要はありません。さらに、ゲームがライブになると、予想以上にクラッシュします。テスト下で完全に動作していたサーバーは、突然、全負荷で多数のバグを公開し、プレイヤーが期待していなかったことを行います。

ほとんどのMMORPGは、実際のゲームデータではなくても、アカウント関連情報にSQLデータベースを使用することに注意してください。ゲームの状態を一貫した状態に保つことよりもさらに重要なことは、課金状態の一貫性を保つことです。ゲームデータベースが破損する最悪のケースは、毎日のバックアップからデータベースを復元する必要があることです。アカウントデータベースが破損する最悪のケースは、すべてのチャージバックが原因で破産することです。

あなたのプロジェクトでは、おそらくどちらの方法でも行くことができます。同時ユーザーが1000人であっても、最近のSQL ServerがコモディティPCで処理できる限界を押し上げることはおそらくないでしょうが、多くはトランザクションの性質に依存します。SQLおよびリレーショナルデータベースの設計に精通している場合は、これで十分です。プレイヤーの現在のヒットポイントのようなものについては、これらのような統計は必ずしも一貫している必要はないので、定期的にデータベースに保存したいだけかもしれません。(PvPゲームでは...)モンスターHPのようなものをデータベースに保存しないでください。ほとんどのゲームでは、プレイヤーに関連するデータのみが永続的です。

一方、SQLウィザードでない場合は、メモリ内のすべてのデータを簡単に保持して、確実に動作させることができます。SQLデータベースは一貫性と信頼性を簡単にしますが、自動ではありません。データベースの設計が適切でないと、パフォーマンスが低下し、不整合が生じる可能性があります。トランザクションは、そうしない限りアトミックではありません。パラメータ化されたステートメントを宗教的に使用しないと、SQLインジェクション攻撃にさらされることになります。


0

さまざまなゲームがさまざまな方法で物事を保存します。多くの場合、ゲーム会社はこれを行うための何らかの方法を作成し、ほとんどのゲームは同じ方法を使用します。もちろん、異なるスタジオはしばしば異なる方法を使用します。SQLは確かにゲームに使用されます。たとえば、CCP(EVE)はSQLサーバーのネットワークを持っています(少なくとも持っていました)。その他、多くのファイルを使用します。

さまざまなゲームデータトランザクションを処理するために、不可知論の「データブローカーメカニズム」を作成することから始めますか。とにかくテストしているだけなので、ゲーム自体の観点から、ストレージについてあまり気にする必要がないメカニズムを作成します。つまり、ホストアプリケーションからこれをどのように処理するかに集中してください。

個人的には、ゲームとブローカー自体を書き直すことなく、実際のストアを切り替えることができれば素晴らしい資産になると思います。ブローカーが通信するための同じインターフェースを持つ別のモジュールに切り替えるだけです。

データを保存すること自体は問題になりそうにありません。ホストとすべてのクライアント間で、そのストアとの間で効率的にデータを配送することは、より複雑になる可能性があります。プレーヤーのデータセット全体を出荷しますか、それとも複数の部分に分割する場合、どの粒度でパーティション分割するかなどを選択します。

データを出荷するための1つの形式はXMLです。そうすることで、簡単に動的にすることができます。1つの文字と複数の文字、または1つのアイテムとアイテムのコレクションなどデータを実際に保存する方法。

別の方法はバイナリで、これは出荷の点ではより効率的ですが、他の状況ではより多くのコストが発生する可能性があります。

1,000クライアントでは、クライアントごとに10 MBを簡単に保存し、10 GBの有効なRAMのみを使用して、そのデータを管理するためにシステム管理RAMを追加できます(たとえば、1 GBまたは2 GB)。既に使用可能なデータ構造にあるホストのRAMに保持することができます。そして、誰がオンラインであるかに応じて、アクティビティに応じてさまざまな頻度で動的にロード/保存します。

各クライアントの情報を個別のファイルに保存することもできます。


0

RAMに*オンライン*プレーヤーを保持し、ログアウト時にemをデータベース(SQLite?MySQL?)にプッシュします。ログアウト中にIOが停止するのが心配な場合は、各ログアウトに独自のスレッドを指定し、メイン/ゲームスレッドでは実行しないでください(実際、すべてのオンラインプレーヤーに専用のプレーヤースレッドを保持しているため、ネットワークコードが非常に簡単になりました非同期ネットワークIOアプローチを行うよりも)

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