XFLAGスタジオの開発者ブログ一本めということで、モンスターストライクのシステムについてざっくりと書いてみます。細かなところはそのうち別の人が書いてくれるでしょう :-)
スマートフォンゲームであるモンスターストライク(以下モンスト)は、スマートフォンアプリとして動作する"クライアント"と、ゲームのパラメーターや進行状況などの重要なデータを管理する"APIサーバー"、最大4人のマルチプレイにかかるリアルタイムなデータ通信を中継する"TURNサーバ"の、大まかに3つの要素で構成される情報処理システムです。
(図 client/API server/Turn server, CSVなどはAPIサーバーの一要素として記述)
ほかにもサーバーやネットワークの監視系システムや、解析系システム、カスタマーサポート系システムなどなど、"ゲーム事業"を滞りなく遂行するための様々なサブシステムを内包しています。
今回は主要3要素のうち、スマートフォンアプリからは見えないAPIサーバーとTURNサーバを簡単に取り上げます。
APIサーバーはゲーム進行に必要な情報をクライアントに提供・管理するWebアプリケーションサーバです。
(図, clientがMsgPackでreqして、RDBMSその他とやりとりする図)
A10のロードバランサー配下に約200台超のLinuxサーバーを配置してクライアントと通信しています。APIサーバは一般的な基盤ソフトウェアを土台として、XFLAGスタジオが開発しているサーバアプリケーションを実行しています。 (図 A10の写真)
APIサーバーのロジックはRubyで記述しています。Pardinoを使用し、RDBMSの操作にはActuveRecordを使用します。Ruby on Railsはつかいません。処理時間の大きな処理はResqueのジョブキューに投入して複数のワーカーノードで分散処理します。
(図 Ubuntu/nginx/unicorn/pardino)
永続化が必要な情報はMariaDBで管理します。MariaDBはActive-Standbyのペアを基本として、要求の増大に対してはまずスケールアップで対応します。必要に応じてテーブルセットごとに別のActive-Standbyペアに分散配置し、さらに要求の高いテーブルについてはシャーディングして対応しています。なんやかんやでMariaDBのサーバーは200台以上動いています。
(図DB x200以上, 32〜192GB, SSD/ioDrive, OS領域を含むHDDレス)
頻繁に使用するホットデータはmemcachedで保持します。memcachedは2つのキャッシュプールを同時更新することで、データ構造を変更する際にもスムーズな移行とパフォーマンス低下を防いでいます。
ちなみにモンスターストライクのシステムは複数のデータセンターにサーバーを配置しています。仮にデータセンターがまるごと1つ停止しても、残ったデータセンターでゲームを提供し続けられる構成をとっています。
スマートフォンは携帯電話キャリアや家庭のWi-Fiなど様々なネットワークから利用されます。ほとんどの場合ネットワークのレイアウトによる制約からクライアントどうしは直接通信できませんが、インターネット上に配したTURNサーバーが仲介することで仮想的なpeer-to-peer通信を実現しています。
モンスターストライクのTURNサーバーはTURN - Traversal Using Relay aroud NATプロトコルを実装したオープンソースソフトウェアをベースに、大規模なマルチプレイ環境の安定提供に必要な様々な改良を加えて利用しています。
(図 TURNをつかったやりとり)
TURNサーバーは一台あたり平時で約10000セッション(数字適当なのであとで治す)を同時に処理するよう調整しています。ちなみにTURNサーバーはゲームの"状態"を保持しない単純なTCPリレー装置として振舞うので計算機資源への要求は少なく、大量のセッションを同時に扱うことができます。もちろん全てのマルチプレイセッションを1台でまかなうのは不可能なので、複数のTURNサーバーをクラウド上に並列配置しています。
とりあえずサワリとしてこの辺で。引き続きモンスターストライクをはじめとしたXFLAGスタジオで扱う技術要素や、スタッフの愚痴を少しずつ書いていく予定ですので、以後お付き合いのほどよろしくお願いします。