モバゲーから提供されているソーシャルゲーム『魔法少女リリカルなのはINNOCENT』は、企画・開発・運用を( 株) ユビキタスエンターテインメントが行っています。このサービスを支えるインフラは物理サーバと仮想サーバのハイブリッド構成となっており、( 株)IDCフロンティアのクラウドサービスが採用されています。本稿はこの両社から、人気ソーシャルゲームならではのデータを交えながら、DevOps実現に向けての取り組みを披露してもらいます。
どんなゲームなの?
『魔法少女リリカルなのはINNOCENT 』は2013年3月にモバゲーにてリリースされたソーシャルゲーム[1] です。原作者の都築真紀氏がこのゲームのために構築した世界観、従来のカード型ソーシャルゲームのシステムを踏まえつつも他作品に類を見ないリアルなバトルシステムと豊富なスキル(100種類超) 、そして作品内の進行度によって開放される完全書きおろしストーリーが大変好評をいただいており、毎月10万人以上のユーザがプレイする作品となりました。
この作品の企画的に大きな特徴の1つは「ゲーム内のキャラクター達も、プレイヤーとまったく同じカードゲーム『ブレイブデュエル』をプレイしている」ということです。このため「プレイヤーが参加している期間限定ゲーム内イベントに、ゲーム内のキャラクター達も参加して一緒に遊びながら、ときには感想を聞いたり、ときには共に成長したりできる」という臨場感を持ったおもしろさがあります。
ユビキタスエンターテインメント(以下、UEI)はセブン・アークス様と共に、この作品の企画・開発・運用すべてを担当しており、筆者、水野は企画ディレクションと開発・運用アーキテクチャの設計を行いました。
本稿では前後編に分け、本作品がDevOpsの考え方に基づいてシステム設計されていることと、その概要、運用担当の宮嶋からはインフラ設計と実際の運用に際して収集データを基にどういったことを裏側で行っているのか、さらに次回の後編では、そのインフラを支えているIDCフロンティアのクラウドサービスにまで踏み込んで、ソーシャルゲームの裏側のお話をしたいと思います。
ソーシャルゲームは眠らない
最近あらためて「DevOps」という言葉をよく見聞きします。DevOpsとは2009年にベルギーで始まった「DevOps Days」からポピュラーになってきた言葉で、筆者自身は2011年のサンタクララで行われたWebパフォーマンスと運用に関するコンベンション「O'reilly Velocity Conference」で初めて耳にしました。
それは日本語で直訳してしまうと「運用開発」ではありますが、それでは言い尽くせないほどに深い概念です。
WikipediaのDevOpsの項目は最近のものでは変わってしまいましたが、初期の記述に「DevOpsは、開発部門(アプリケーションエンジニア/ソフトウェアエンジニア)と技術運用部門の、コミュニケーション・連携・調律を行うための、手法とシステムが一連となったプロセスである。」( 注2 ) 「 その目的は、良い品質のソフトウェアプロダクトやサービスを的確に素早く提供することによって、ビジネスゴールへと到達することを容易にするためにある。」( 注3 )と書かれていました。
このように、DevOpsは「サービスのリリースサイクルを速めようぜ!」とか「開発と運用が仲良くしようぜ!」という単純なものではなく、全体をとらえて「ビジネスゴールへ到達することを容易にしよう!」という目的を見据える概念であるのが深いところです。
筆者は、いままでにオンラインゲームやWebサイト、スマホアプリの開発に100以上かかわってきました。その経験から、本作品のようなソーシャルゲームの運用開発における、その目的と典型的な4つの特徴は次のようであると考えています。
【目的】
プレイヤーに、常に新鮮なイベントやシステムと、成長素材を提供し、安定してゲームを遊んでもらうこと。
【4つの特徴】
1ヵ月に数十回の小規模開発=「カード追加」「 UI改善」「 小機能追加」のリリースが発生すること
1ヵ月に数回の中規模開発=「ゲームイベント」のリリースが発生すること
数ヵ月に一度の大規模開発=「新規ゲームイベント」のリリースが発生すること
技術者の調査が必要なユーザサポート問い合わせが日に数件~数十件必ず発生すること
特徴の4つを見てわかることは、とても複雑かつ密接に開発と運用が結びついているということです。そのため、長期にわたってトラブルなく運用することは非常に難しく、実際のところ、筆者もそれは完全にはできていません。そこでプレイヤーの皆さんにおなじみ(?)の「補填」や「詫び石」が発生する事態になったりする場合があります。
しかし、トラブルを完全になくすことはできなくても、少なくすることにエンジニアリングで挑戦するのが技術者のはずです。ソーシャルゲームにおいても開発と運用は密接な関係にあり、どちらかに寄ってしまったり完全に切り離すことはできないことがわかりました。それならば、戦場の狙撃兵が観測手と組み、一体となってその目的を達成するように、本作品の目的のためには開発と運用を統合して考えなければなりません。そのための技術としてDevOpsを必要としたのです。
さて、ここからは弊社内「Ops」側担当の宮嶋から、インフラ整備と運用に関するエンジニアリングを事例を交えて紹介します。
[2] 原文:DevOps is a set of processes, methods and systems for communication, collaboration and integration between departments for Development (Applications/Software Engineering) and Technology Operations.
[運営サイド]インフラ構成について
フィーチャーフォンやスマートフォンのブラウザでプレイされるソーシャルゲームは、ゲーム専用機のパッケージで提供されるゲームとは異なり、ゲームに必要なデータをほぼすべてサーバ側で保持しています。そのためサーバに要求される性能や機能の水準も高くなります。また同時利用者数が多く、イベントなどが実施されると普段の数倍以上の利用者数になることもあり、サーバ負荷が変動しやすい性質を持っています。そのためシンプルな構成を保ちながら運用しやすく、負荷に応じて柔軟に性能を変化させやすいインフラ構成を検討する必要があります。
LAMP構成中心の設計
少人数での運営作業は、運用コストを見直し、低下させる方針が重要となります。自分たちが使い慣れた、動作実績があり設定が把握しやすいミドルウェアを利用すると、運用コストの削減につながります。
また、ソーシャルゲームのプラットフォーム側で提供されている機能(画像キャッシュ機能)など、利用可能なものは自前で構築しないなどの割り切りも行います。我々が本作品で利用したミドルウェアと利用方針は次のようになります。
ロードバランサとしてのNginx
ロードバランサとして、NginxをWebサーバの上段ネットワークに配置します。ここで参照頻度の高い画像配信と、リバースプロキシサーバとして機能させ、Webサーバにトラフィックの分散を行います。
アプリケーションサーバとしてのApache
Webサーバ兼アプリケーションサーバとして、Apache HTTP Serverを利用します。PHPで記述されたゲームプログラムを実行し、Flashのリアルタイム合成や、カード画像などの一部画像ファイル名のハッシュ化も行います。
ファイル名のハッシュ化を行うとファイル名が推測しにくくなり、不正利用の防止につながります。
データストアとしてのMySQLとMemcached
ゲームユーザごとのプレイデータとゲームプログラムで利用するゲームマスタデータはデータベースサーバのMySQLで保持しています。Memcachedは利用頻度の高いゲームマスタデータのキャッシュに利用し、MySQLへの接続頻度の低下を図っています。
MySQLは最新安定版であるMySQL 5.6を採用しています。MySQL 5.6は高速であるだけでなく、mysqlfailoverコマンドを利用したフェイルオーバー機能も備えています。しかし、このフェイルオーバー機能は利用できるストレージエンジンが限られるなど制限もあり、運用面では課題が残る部分もあります。
MySQL 5.6での特筆すべき機能として、遅延レプリケーションがあります。遅延レプリケーションでは、通常のレプリケーションとは異なり、SQLの実行を事前に設定した時間の間で遅延させることができます。
たとえば意図しないデータ削除などのオペレーションミスが生じた場合、「 削除処理がまだ実行されていない状態のデータ」を容易に入手できるため、バックアップからの復元といった負担の大きな作業を行わなくてもよいメリットとなります。
トラフィック削減のためデータ通信の圧縮
サーバのCPUコア数やメモリはクラウド環境を利用することで柔軟に変化させることができますが、ネットワークインターフェースの通信速度はサーバのスペックに依存する部分を除いては柔軟な変更を行いにくい部分となります。このように変更を行いにくい部分はボトルネックになりがちです。
そのためデータ通信の圧縮を行うと、トラフィックの削減を図ることができ、ゲームのレスポンス向上にもつながります。
Apacheではmod_deflateモジュールを利用してコンテンツの圧縮を行い、PHPでMySQLとMemcachedの接続時に圧縮する設定や、MySQLレプリケーション通信間の圧縮設定を行うなど、さまざまな個所で圧縮通信設定を行っています。
クラウド環境を選ぶ理由
使い慣れたミドルウェアを利用するため、『 魔法少女リリカルなのはINNOCENT』ではIaaSクラウド環境を利用しています。IaaSクラウド環境は、クラウド事業者によって利用できる機能が異なります。サーバスペックに現れない部分は実際に利用しなければわかりません。できるだけさまざまなクラウド環境を試して、選択肢を多くすることをお勧めします。
向きと不向き
IaaSクラウド環境では仮想サーバが利用できます。仮想サーバはCPU性能やメモリ容量によって料金が異なりますが、仮想サーバは物理ホストサーバの上で動作する以上、サーバの性能を専有できず、さまざまな影響によって性能にバラつきが生じます。我々の場合、公開されているベンチマークデータを鵜呑みにせず、自分でSysBenchやfio、mysqlslapなどのベンチマークツールを用いて確認したあとは、厳密な性能の測定にはこだわらず、利用想定、仮想サーバの負荷状況に応じてサーバスペックや台数を柔軟に変化させる方針を取っています。
仮想サーバは簡単に調達でき、自分でミドルウェアをセットアップしたあとのサーバイメージをコピーすることも容易に行えます。
Webサーバはアクセス状況によって負荷が変動しますので、仮想サーバを利用した構成を取ると、急なアクセス増にも楽に対応が行えます。
DBサーバはI/Oアクセスが多いため、安定したI/O性能がないとサーバ性能への影響が大きくなります。I/O性能は仮想サーバでは安定して確保しにくいため、クラウド事業者によっては通常のストレージとは別に、高速なSSDや安定したIOPS(Input/Output Per Second)を供給するストレージを提供するところもあります。
しかしどうしても安定した性能を確保したい場合は、物理サーバの利用も選択肢になります。物理サーバは高速なI/O性能を誇るioDriveを搭載したものや、大容量のメモリが選べるものがあり、それらの性能が専有できるため、仮想サーバと比較して性能面でのバラつきが小さくなります。反面、仮想サーバのように調達が容易に行えず、納期に時間がかかったり、故障の影響を受けやすいなど柔軟な運用が行いにくいデメリットもあります。
本作品では事前登録会員数が10万人を超え、ユーザ活性が非常に高いことが想定されたため、すべて仮想サーバを利用した構成とせず、DBサーバは物理サーバを利用する構成を取りました。初期構成が図1 となります。
図1 『 魔法少女リリカルなのはINNOCENT』サーバシステム初期構成
仮想サーバと物理サーバはL3接続されているため、ルーティング設定を行えば仮想サーバと物理サーバの区別なく相互接続が可能となります。
ソーシャルゲームでのクラウド利用
小さい構成から始めて、利用状況に応じて増強する「スモールスタート」構成はクラウド環境が向いていると言われます。ソーシャルゲームもリリース後の状況が読みにくい部分はありますので、リリース初期はクラウド環境を利用し、その後ユーザ数の増加に伴い安定した性能を確保するためにオンプレミス環境へという方法を選択されている他社SAPの方も少なくありません。
もちろんオールクラウド環境だと不安定で利用に耐えないということはなく、そのソーシャルゲームをどのように成長させていくかという想定のもと、稼働環境を検討することが重要です。
本作品もそれにならい、仮想サーバと物理サーバのハイブリッドクラウドから開始し、最終的にはオンプレミス環境を利用するという成長過程の想定をしています。
クラウド事業者の違い
IaaSクラウド環境を提供する事業者はAWSをはじめ、国内にも多数あります。仮想サーバ機能はどこでも利用できますが、機能面でベンチマークとなるのはAWSです。AWSで当たり前に利用できる機能が、他社では搭載されていないことはよくあります。そのため、AWS以外のクラウド事業者を利用する場合は、ある程度機能面での不足の割り切りを行ったうえで、強みや独自性が生かせる事業者を選択しています。
本作品では、サーバとネットワーク部分はIDCフロンティアクラウドを利用し、DNSやバックアップストレージにAWSのRoute53とS3を利用しています。
IDCフロンティアクラウドは仮想サーバの費用対性能が高く、iDC(Internet Data Center)も運用し、クラウド環境と物理サーバのハイブリッド利用オプションがあるためソーシャルゲームの成長過程の想定に合致していました。
AWSは基本的にインターネット越しにはなりますが、AWS外からもサービスの利用が可能なため、クラウド事業者間でハイブリッド利用することが可能です。
IaaSクラウドはベンダーロックインのような縛りがほとんどないため、事業者ごとに有利な部分を選択的に使うと運用面でも費用面でもコストを下げることができます。
イベント中の運営で何が起きているのか?
『魔法少女リリカルなのはINNOCENT』では現状、月に1回程度イベントを実施しています。イベントは約1週間程度実施され、その期間中の活動ポイントによって報酬が異なります。イベント期間中は普段の数倍のトラフィックが生じることも珍しくなく、イベントの参加者だけでなくイベント運営側にとっても、大変忙しい期間となります。
イベント準備期間では
本作品では原作者の方が監修し、企画後に毎回イベントを新規に実装しています。そのため、使い回しのイベントがほぼありません。企画ごとに新規実装しているため、企画内容によってサーバにかかる負荷パターンが異なります。
たとえば、Flashアニメーションを多用したイベントの場合は、Flashのリアルタイム合成を行っているWebサーバに負荷がかかり、ユーザ間対戦型イベントの場合はユーザのプレイデータを保持するDBサーバに負荷がかかるなど、増強するサーバタイプが異なる性質を持ちます。
どのサーバをどのようなタイミングで増強して行くのかは悩ましいところではありますが、DBサーバに物理サーバを選択しているため、場合によっては調達に時間がかかる恐れがあります。増強に遅れを生じさせないためには、できるだけ事前の負荷想定が重要になってきます。
イベント時の負荷推定を行うためには、日頃からサーバとネットワークの負荷状況を把握しておく必要があります。リソースの利用状況の把握にはZabbixを利用し、可視化しています。
イベントの開始
イベントの開始から終了までのロードバランシングサーバのトラフィックの一例が図2 のグラフとなります。イベント直前の50Mbps前後のトラフィックから、7月20日18時から19時のイベント開始直後に、一気に200Mbps超のトラフィックに急増しています。
図2 イベント開始から終了までのロードバランシングサーバのトラフィック例
このとき運営側では、事前想定と負荷状況がどの程度違うかを調査しています。調査ではFluentdを利用したサーバのログ収集と、MySQLのクエリ状況を中心に確認しています。
ソーシャルゲームではWebアプリケーションのレスポンスタイムが重要な指標となります。Apacheのログフォーマットを変更し、「 %D」を付与するとマイクロ秒単位でレスポンスタイムの記録が可能です。Combinedフォーマットを利用している場合の変更例は次のようになります。
LogFormat "%h %l %u %t \"%r\" %>s %b ュ\"%{Referer}i\" \"%{User-Agent}i\" %D" ュcombined
レスポンスタイムに5秒以上要しているレスポンスが一定数以上あると、ソーシャルゲームのプラットフォーム側から強制的にメンテナンス状態に移行される恐れがあります。この状況を避けるために1秒以上レスポンスに時間を要しているものは調査対象に分類します。
MySQLでは処理に時間がかかったクエリを記録することができ、そのクエリをスロークエリログに記録することができます。スロークエリの記録しきい値はMySQL 5.1以降であれば、動的に変更することができます。通常は0.5秒程度をしきい値に設定していますが、より詳細に調査したい場合は次のようにしきい値をゼロ秒に設定し、一時的にすべてのクエリ状況を記録することも行います。
mysql>set global long_query_time=0;
すべてのクエリを記録すると負荷が大きいため、確認後は必ず元のしきい値に戻しておくことが重要です。
見つかった問題点は開発側にフィードバックし修正を行います。残念ながらイベント開始後に発覚した問題点には、改善に時間を要するものもあります。その場合は、ゲームの一部機能停止や、影響が大きい場合は緊急メンテナンスを行い、イベントの一時休止を行うこともあります。
イベントの中盤
イベントの中盤ではリソース監視を継続し、ユーザのイベント参加率を考慮しながら、サーバの増強効果を確認します。この時点ではトラフィックが急増することもほとんどないため、イベント準備期間と開始直後に問題点の改善が済んでいれば比較的落ち着いた状態が保てます。
とはいえ、いつまでも落ち着いた状態のままではいられないため、イベント終盤に向けての計画を確認し、すでに指摘済みの改善点の漏れがないか、イベント開始直後に見つかった一時的にレスポンスが遅いリクエストの再確認を行います。
レスポンスが遅い原因がデータベースへのクエリにある疑いが生じた場合、処理時間が短いが、発行回数が多いクエリを疑います。単純にスロークエリの記録しきい値を変更しても、発行回数が多く、問題があるタイプのクエリの発見は難しいため、MySQL付属のmysqldumpslowコマンドを利用します。
mysqldumpslow -s t mysql-slow.log
上記のコマンドを調査したいスロークエリログに対して実行すると、クエリ処理時間と実行回数を計算した合計処理時間が、上位のものからソートした結果として得られます。このコマンドの結果を分析し、問題が見つかった場合は開発側にフィードバックを行います。
イベント中盤ではユーザの振る舞いも安定しているため、この時点で発見された問題を無理に改善しようとすると、結果として必ずしも最適にならない恐れがあります。そのため修正するかどうかはイベント終盤時に問題になりうるかどうかという視点で協議し、判断を行います。
イベントの終盤
イベントの終盤が迫り、とくに最終日になるとイベント参加者も追い込みに入ります。
図2 の7月26日18時ごろから見られるように、イベント終了間際になると200Mbps超のトラフィックがさらに急増し、600Mbps超にもなります。
トラフィック急増の原因は、このイベントの場合はユーザによるWebサーバ上でのFlashリアルタイム合成要求数の増加なのですが、合成処理によるCPU利用率の上昇がレスポンスタイムに大きな影響を与えないように、Webサーバのロードアベレージを確認します。
図3 のグラフがイベント中のWebサーバのロードアベレージになります。イベント終了の1~2時間前ぐらいからトラフィックが急増する傾向があるため、サーバ起動時間を考慮して事前プロビジョニングを行います。図4 のグラフでは16時と20時にサーバを追加し、最終的にはWebサーバの数は60台になりました。
図3 イベント中のWebサーバのロードアベレージ例
図4 図3のイベント終了間際を拡大
イベント期間中は定期的にイベントランキングの公開を行っていますが、イベント終了間際では公開を停止しています。これは参加者による駆け込みアクセス増の防止を目的としています。
“駆け込みアクセス増” とは、イベント終盤になると、ランキング報酬が獲得できる順位争いが加熱化し、ランキングを取得する目的で集計間際に大量のポイントを獲得されることがあります。フィーチャーフォンやスマートフォンのブラウザでの利用を想定したゲームではありますが、PCなどからツール等を利用して参加する一部ユーザが存在します。ツールを利用するとフィーチャーフォンやスマートフォンのブラウザでは実行不可能な速度でゲームへの参加が可能になるため、対策として駆け込みアクセスなどの連続アクセスにはしきい値を強化するなど監視を強化し、ユーザ間で公平なリソース利用となるように注意しています。
終了間際のリアルタイム最適化
イベントの終了が近くなると、これまで行った最適化の効果を検証し、イベントを無事に終了させるためにリソース監視だけでなくDBサーバで実行中のプロセスを確認し、問題の早期発見に努めます。
MySQLで実行中のプロセスを確認するには次のコマンドを実行します。
mysql>show full processlist;
イベントの終盤ではユーザの行動ログが蓄積され、データが肥大してきます。データが肥大してくると、これまでに行ったスロークエリログを利用したクエリの改善が有効でなくなるケースが存在します。
図5 のグラフはユーザのプレイデータが保持されているDBサーバ上で、Select Scanされた数を記録したものです(これまでのサンプルとは別のイベントのもの) 。Select Scanはテーブルやインデックスの先頭行から全件検索を行った回数を意味します。
図5 DBサーバ上でSelect Scanされた数を記録したもの
SELECT文を用いたクエリのチューニングではインデックスを使用して探索する行数の範囲を少なくするのがセオリーですが、全件探索を行う場合もあるため、一定数のSelect Scanは存在します。しかし、Select Scanが意図せず急増している場合はMySQLが利用するインデックスが変化した可能性があるため、調査を行います。
MySQLのオプティマイザはデータ量と利用頻度によって利用するインデックスを変化させるため、事前のクエリ実行計画結果と利用されるインデックスが違ってしまう場合があります。その場合は「force index(インデックス名)」でインデックスのヒントをオプティマイザに与え、利用するインデックスを変更するように発行するSQL文を変更します。
場合によっては、クエリの実行速度を最優先するためにインデックス追加や削除などをイベント中に最適化することもあります。MySQL 5.6ではインデックスの追加と削除がオンラインで可能なため、イベント終盤でゲームの中断を行わずに済みます。
イベント後
無事にイベントが終了できると、運営側もやっと一息つけます。イベント終了時刻を超えるとトラフィックが急減するため、イベント中に増強したサーバを停止し、課金を抑えるといったイベント終了作業を行います。
また、想定よりも悪かった部分や良かった部分を次回のイベントに活かせるように抜き出し、調査項目に挙げるなどの振り返りを行います。振り返りは地道なことですが、地道なことを継続し、経験を蓄積することが、企画・開発・運用が協力した少人数での運営には重要になります。
次回予告
今回はDevOpsの考え方を実践するソーシャルゲーム『魔法少女リリカルなのはINNOCENT』のインフラ構築の方針、データ分析による継続した改善について我々の取り組みを紹介しました。
後編 では、DevOpsのおもに「Dev」に重きを置いたソーシャルゲーム開発の裏側と、クラウド事業者のIDCフロンティアから見たソーシャルゲームトラフィックのさばき方を紹介したいと思います。