オンラインゲームのデータベース。 Allods OnlineからSkyforgeまで

ゲーム開発について話すときは、通常、シェーダー、グラフィックス、AIなどについて話します。 ゲームプロジェクトのサーバー側に影響を与えることはほとんどありませんが、データベースに影響することはほとんどありません。 この厄介な誤解を修正します。本日、Allods Onlineと新しいSkyforgeプロジェクトの開発中に得たデータベースの経験についてお話します。 これらのゲームは両方ともクライアントMMORPGです。 最初の段階では、数百万人のプレイヤーが登録されています。 2つ目は、Allodsチームの腸内で最も厳格な秘密裏にスタジオによって開発されました。



私の名前はアンドレイ・フロロフです。 私はAllodsチームの主任プログラマーであり、サーバーチームとして働いています。 私の開発経験はほぼ10年ですが、2009年10月にしかゲームに参加しませんでした。2010年3月から3年以上チームに所属しています。 Skyforgeサーバーとデータベースに何らかの形で接続されているすべてのものを扱っています。 この記事では、AllodsとSkyforgeの例を使用して、オンラインゲームのデータベースについて説明します。







読みたくない場合は、記事を最後までスクロールして、Game Developers Conferenceのレポートのビデオをご覧ください。 ポストに残っている人にはボーナスがあります-NoSQL-JSONハイブリッドとリレーショナルデータモデルに関するストーリーの形式でレポートに重要な追加。



進化




ゲームベースは典型的なOLTPシステムです(多くの小規模で短いトランザクション)。 ただし、ゲームでのデータベースの使用は、Web、銀行、その他の企業での使用とは多少異なります。 まず、これはゲームのデータモデルが銀行よりもはるかに複雑であるという事実によるものです。 第二に、ゲーム開発者のほとんどのプログラマーは、C ++の厳しい世界から出てきて、彼らにひげとバイナリパッケージングを愛していました。 キャラクターをディスクに保存する必要がある場合、絶対にそれらのすべて、彼らはそれをファイルにシリアル化したい最初のもの。 それが、Allods Onlineでのすべての始まりです。 プログラマーはファイルストレージを作成しましたが、すぐにそれをよく考え、MySQLの下ですべてを書き直しました。 プロジェクトは正常に開始され、人々はプレイし、経験が蓄積されました。



Allodsにあったもの:







数年後、Skyforgeが始まりました。 Skyforgeにはまったく異なる要件があったため、データベースを操作するアプローチを再考する必要がありました。



これらは要件です:







さて、舞台裏を見て、技術思想の進化的発展の過程で私たちがどうなったかを見てみましょう。



建築




まず、サーバーが配布されます。 ベースも配布されます。 第二に、サーバーのアーキテクチャはサービス指向です。 これは、すべてがメッセージを交換するサービスの形式で提示されることを意味します。 ゲームには多数のサービスがありますが、データベースに直接アクセスできるのはトランザクション実行サービスのみです。 一般的に言えば、私の芸術的能力を最大限に活用すると、次のようになります。







写真に描かれているすべての要素が複数のコピーに存在することを考慮するだけで十分です。







キャッシュとしてのアバター




この単純なスキームには1つの重要なポイントがあります。 私たちのアバターはゲームの仕組みのパフォーマンスに必要ですが、副作用として、実際にはデータベース上のキャッシュです。 「このプレーヤーのアイテムを見せて」や「ヴァシリーのアバターはどこにいるの?」などのすべてのリクエストは、このアバターによって処理されます。 プレイヤーがゲームに参加するとき、私たちは彼のアバターをアップロードし、プレイヤーがオンラインである限り彼は生きます。 この簡単なトリックにより、ほとんどの読み取り要求、さらには書き込み要求の一部をデータベースから削除できます。



すべてのプレーヤーデータを2つのカテゴリに分類します。







それでは、データベース内の重要なデータの状態と、別のサーバー上にあるアバターをどのように同期させるのでしょうか? 実際にはすべてが非常に簡単です。 件名を取得するスキームを検討してください。







PostgreSQL




Skyforgeでは、以下の理由を組み合わせてMySQLを廃止しました。







PostgreSQLはこれらすべての問題を解決し、代わりに自動バキュームの問題のみを提供しました。 NoSQLデータベースを使用しないことにしました。 データの一貫性に対する要件は非常に高く、世界中の単一のNoSQLデータベースが、あるアバターから別のアバターにアイテムを一貫してトランザクションで転送することはできません。 この場合の最終的な一貫性は、私たちにはあまり適していませんでした。 それはゲーム体験を大いに台無しにします。



ハイブリッドデータスキーマ




PostgreSQLを使用しているという事実は、データをリレーショナル形式で保存する必要があるという意味ではありません。 リレーショナルデータベースはキーと値のストレージとして使用できます



完全にリレーショナルなモデルは私たちには適していない、なぜなら いくつかのパフォーマンスのボトルネックが含まれています。 たとえば、プレーヤーがいて、彼にはクエストがあります。 プレイヤーは何百ものクエストを完了することができ、ゲームに入るとすべてを表示する必要があります。 リレーショナルモデルを使用する場合、データベースから数百の行を返すように要求する必要があり、これには時間がかかります。 一方、非リレーショナルモデルには多くの欠点があります。定数の欠如、データを部分的に更新できないなどです。



さまざまな実験の後、いくつかのフィールドに非リレーショナルデータが含まれる一連のリレーショナルモデルに満足していることに同意しました。 AllodsとSkyforgeで最近まで、データバイナリの一部をシリアル化し、テーブルのフィールドとして保存しました。 しかし、わずか3週間前にようやくすべてを理解し、JSON挿入を使用してリレーショナルスキーマにデータを保存しました。



次のようになります。



# select * from avatar limit 1;
id | 144115188075857124
position |
{"point":{"x":7402.2793,"y":6080.2197,"z":51.42402},"yaw":0.0,"map":"id:132646944","isLocal":false,"isValid":true}
death_descriptor | {"deathTime":-1,"respawnTime":-1,"sparkReturnDelay":-1,"recentDeathTimesArray":[]}
health | 1250
mana_descriptor | {"mana":{"8":300}}
avatar_client_info | \x
character_race_class_res_id | 26209282
character_sex_res_id | 550995
last_online_time | 1371814800726

      
      







JSON. , PostgreSQL 9.3 JSON. , — PostgreSQL MongoDB PostgreSQL.



Virtual shards




, . ID , , .



ID : — , — ID .



long id = <shard_id> <account_id>



. . . -, virtual shards . , , 15 . , 5 . 215 310. , .



SSD




SSD. RAID-. , , , fsync.



. , 200 , SSD. , SSD ó . SSD WAL PostgreSQL, , . SSD !







, .







, .







, , . . , master—slave , , .



,


.



C .



- .






All Articles