大規模ゲームサービスを運営する3社が語る、複雑・大規模なWebサービスを支える技術とは?
AWS×PHPでの高信頼かつハイパフォーマンスなシステム
最後の登壇者は、株式会社サイバーエージェントの伊藤皓程さんです。
伊藤皓程(いとう・こうてい)/株式会社サイバーエージェント サーバーサイドエンジニア。1989年生まれ。上海市出身。東京電機大学大学院卒後、2015年に新卒で入社。現在は、子会社QualiArtsにてスマートフォンゲームの開発に従事。
■「ボイきら」はこう構成されています。
伊藤さんが開発に参加した「ボーイフレンド(仮) きらめき☆ノート」(以下「ボイきら」)は、2016年11月にリリースされた女性向けリズムゲームです。事前登録者は約3ヶ月で24万人を突破し、リリース後は「App Store」の無料ランキングで1位を獲得するなど人気を博しています。
サービス稼働率は99.5%と、リリース直後のサービスとしては高い数字を残しています。また、APIサーバーのパフォーマンスは、平均レスポンス時間(動的コンテンツのみ)で160ms。これはPHPプロジェクトではかなり早いものであり、1台あたりの最大スループット(c4.2xlarge)も350req/secと高い数字を出しています。
「ボイきら」のアーキテクチャはとてもシンプルなものです。Webview、クライアントにわたすマスターデータ、Assetsなどの静的コンテンツは、すべてCDNを通して配信します。
APIサーバーへのリクエストはすべて動的コンテンツのリクエストとなり、「Elasticache(Redis)」を使用して負荷を分散しています。負荷試験で検証した結果、シャーディングは必要ないという結論を出し、SELECTはすべてReaderに流すことでマスターの負荷を軽減しています。
こうした「ボイきら」の状況を説明した上で、伊藤さんは大規模で複雑なサービスをつくる時には「高信頼・高可用性」「ハイパフォーマンス」を実現することが求められると解説します。
■キャッシュはどう活用すればいい?
まず、サービスの「ハイパフォーマンス」を実現するために重要となってくるキャッシュについて伊藤さんは説明します。
「PHP」は、リクエストごとに独立したメモリ空間を持ち、スクリプトの読み込みとコンパイルが発生します。そのため、リクエストを横断した変数の共有に工夫が必要となり、フルスタックなフレームワークを使用するとリクエストの度にかなりの量のスクリプトを読み込み、パフォーマンス劣化の原因となってしまいます。
そこで「ボイきら」では「APCu+OPcache」を使用することで改善を図りました。
「APCu+OPcache」は、「PHP」内で共有メモリを持つためのモジュールであり、リクエスト間で変数の共有ができます。「OPcache」では、初回のリクエストに対してはスクリプト、コンパイル、最適化と行ったのち、キャッシュから実行します。そして2回目以降はキャッシュから直接実行されるのでパフォーマンスを大きく向上させることができます。
続いて、マスターデータのキャッシュについて。データベースで保存されているマスターは正規化されているため編集は簡単ですが、使用するときには、マスターデータと連携して、様々なAPI単位で整形してから使用していました。これでは同様のロジックが重複し、無駄が多くなります。
そのため、あえて、正規化されたマスターデータを、構造を変えてキャッシュすることで、各APIで整形する必要がなくしました。ロジックがシンプルになるためパフォーマンスが向上します。
また、「DBへのアクセスの回数を減らす」「リクエストの最後で初めて更新処理を実行したい」という目的のためにプレイヤーデータもキャッシュしています。
■「ボイきら」での自動化は?
サービスの「高信頼・高可用性」を担保する際に重要となる自動化・自動生成に関して、「ボイきら」では以下を導入しています。
・スプレッドシートから「DDL」の自動生成
・DBのスキーマからModelクラスの自動生成
・DBのスキーマからテストのMockの自動生成
・DBのスキーマからDBの「JsonSchema」を自動生成
・DBの「JsonSchema」からクライアントのクラスを自動生成
・DBの「JsonSchema」からマスターデータのバリデーションを自動化
・「Req/Res」の「JsonSchema」からクライアントのクラスを自動生成
・「Req/Res」の「JsonSchema」からAPI定義書を自動生成
プレイヤーデータは差分管理し、ログイン時にクライアント側に全プレイヤーデータを返す方法を採用。以降は変更、追加、削除があったもののみサーバー・クライアントの基盤部分で自動的に感知しています。これにより、各種APIでクライアントに返却するデータは、API実装者がクライアントにビュー表示する部分だけで済むようになっています。
その結果クライアントではそのデータを基盤で受け、内部データの書き換え処理をするので、API実装工数の削減を実現できています。
最後に、冗長性の担保やコスト的にもメリットのある「Aurora」について紹介し、伊藤さんの講演は終了しました。
当日のスライドはこちらに公開されています。
Q&Aと懇親会!
3名の講演の終了後は、会場からの質問タイムです。
—— スプレッドシートから「JsonSchema」を生成しているのでしょうか? また、企画側もデータベースを理解して設計しているのですか?
伊藤 スプレッドシートから「JsonSchema」ではなく、DBの「DDL」を生成しています。そもそもスプレッドシートの定義はサーバーエンジニアが書いているので、企画側が管理することはないですね。
—— 「Redis」と「Memcached 」は使い分けていますか?
久保田 完全に切り離していますね。新しいリクエストはほぼすべて「Redis」にしようと思っていて、「Memcached 」は必要に応じて使おうと考えています。
最後は懇親会です。久保田さんの音頭でスタート!
参加者が多かったこともあり、ピザの数もdots.史上最大級です!
質問タイムでは時間が足りなかったこともあり、参加者の皆さんは盛んに交流されていました。
またの開催を心よりお待ちしています!