モバイルゲーム解析プラットフォームの作成 - リファレンス アーキテクチャ

モバイルゲーム アプリケーションでは、プレーヤー テレメトリーとゲームイベントに関する膨大なデータが生成されます。このデータを使用して、プレーヤーの行動や、ゲームへのエンゲージメントを詳しく知ることができる可能性があります。モバイルゲームには、多数のクライアント デバイスが使用され、インターネット接続が不定期で低速であり、バッテリーや電源管理の問題が生じるという特性があり、プレーヤー テレメトリーやゲームイベントの分析は特有の課題に直面しています。

このリファレンス アーキテクチャでは、Google Cloud Platform で大容量のプレーヤー テレメトリー データを収集、保存、解析する高度な手法を使用できます。

具体的には、モバイルゲーム イベントを解析するための、2 つのメイン アーキテクチャ パターンを学習します。

  • リアルタイム処理: ストリーミング処理パターンを使用して個々のイベントを処理します
  • 一括処理: バッチ処理パターンを使用して集約されたイベントを処理します

ゲーム テレメトリーのリファレンス アーキテクチャ

図 1: ゲーム テレメトリーのリファレンス アーキテクチャ

図 1 に、両方のパターンの処理パイプラインと、結果をさらに探索、可視化、共有するための、いくつかのオプション コンポーネントを示します。このリファレンス アーキテクチャは可用性が高く、データ量の増加に合わせてスケールできます。また、このアーキテクチャはデータ解析パイプラインのマネージド サービスのみで構成されており、仮想マシンを実行したり、オペレーティング システムを管理したりする必要はありません。特にこれは、ゲームサーバーが App Engine でユーザー認証を行う場合に有用です。この記事の残りの部分では、このアーキテクチャについて詳しく説明していきます。

ストリーミング パターンを使用したリアルタイム イベント処理

このセクションでは、多数の異なるソースから多数のイベントを同時に取り込み、処理して、解析するサンプル アーキテクチャ パターンについて説明します。処理はゲームでイベントが発生したときに行われるため、リアルタイムで応答し、決断を下すことができます。

多くのモバイルゲームでは、多数のイベント メッセージが生成されます。プレーヤーによってトリガーされるものや、設定された時刻にトリガーされるものなどがあります。この結果、データセットは無制限になり、前もって処理すべきイベントの数はわかりません。このため、なんらかのストリーミング実行エンジンを使用してデータを適切に処理する必要があります。

プレーヤーが強力なモンスターを倒すための冒険の旅に出かけて、邪悪な敵と戦うロール プレーイング ゲームのモバイルアプリがあるとします。プレーヤーの進捗を追跡するために、一般的なイベント メッセージにはプレーヤーの一意の ID、イベントのタイムスタンプ、冒険を示すメトリック、プレーヤーの現在のヘルスポイントなどが含まれています。おそらく、playerkillednpc のイベント ID を持つバトル終了イベント メッセージを示す、次の例のようなものになるでしょう。

{
"eventTime":"2015-10-27T20:34:12.675362426+08:00",
"userId":"gamer@example.com",
"sessionId":"b6ff8881-0c30-9add-374c-c32052cee256",
"eventId":"playerkillednpc",
…
"attackRoll":17,
"damageRoll":13
}

この例にはバトルに関連するイベントがありますが、イベント メッセージにはゲーム内購入イベントなど、ビジネスに関連するあらゆる情報が含まれる可能性があります。

将来、データに関して尋ねる必要が生じる質問の内容を予測することはできないため、可能な限り多くのデータポイントをログで記録するのが優れた戦略と言えます。これにより、将来データを照会するために必要なコンテキストをさらに得ることができます。たとえば、あるプレーヤーが 50 セントのゲーム内購入を行ったという情報と、冒険 15 でボスに立ち向かうために強力な呪文を購入したが、その購入の 30 分前にプレーヤーが続けて 5 回ボスによって倒されたという情報を比較して、どちらのほうがより洞察力が高いと言えるでしょうか。豊富なイベントデータを取得すると、ゲーム内で実際の行われていることに対して、さらに深い洞察を得ることができます。

メッセージ ソース: モバイルか、ゲームサーバーか

イベント メッセージのコンテンツ フィールドに関係なく、イベント メッセージを、モバイルアプリを実行しているエンドユーザー デバイスから直接 Cloud Pub/Sub 取り込みレイヤに送信するか、ゲームサーバーを介して送信するかを決定する必要があります。ゲームサーバーを介する主な利点は、認証と検証がアプリケーションによって処理されるということです。欠点は、モバイル デバイスから着信する大量のイベント メッセージを処理するために、その容量を処理する追加サーバーが必要になるということです。

ゲーム クライアントとゲームサーバー イベントのリアルタイム処理

図 2: ゲーム クライアントとゲームサーバーからのイベントのリアルタイム処理

データのソースに関係なく、バックエンド アーキテクチャは大部分が同じです。図 2 に示されているように、以下の 5 つの主要部分があります。

  1. リアルタイム イベント メッセージは、数百万台のモバイルアプリなど、多数のソースによって送信されます。
  2. 認証はゲームサーバーによって処理されます。
  3. Cloud Pub/Sub はこれらのメッセージを取り込み、一時的に保存します。
  4. Cloud Dataflow は JSON イベントを構造化されたスキーマベースのデータに変換します。
  5. このデータは BigQuery 分析エンジンに読み込まれます。

Cloud Pub/Sub: スケーリング時のイベントの取り込み

このロード作業を処理するには、これらのイベント メッセージを受信して一時的に保存できるスケーラブルなサービスが必要です。個々のイベントはサイズが非常に小さいため、メッセージの合計数のほうが全体的なストレージ要件よりも問題になります。

この取り込みサービスのもう 1 つの要件は、複数の出力方式に使用できるという点です。つまり、イベントは複数の宛先でコンシュームされる必要があります。最終的に、各宛先が新しいメッセージをフェッチするためにポーリングするキューとして動作するサービスと、受信時にイベントを積極的に送信するプッシュ メソッドの間で選択できます。

Cloud Pub/Sub サービスではこれらの機能がすべて提供されます。図 3 は、推奨される取り込みレイヤ、1 秒間に数百万件のメッセージを処理する機能、それらを最大 7 日間永続ストレージに保存する様子を示しています。Cloud Pub/Sub はパブリッシュ / サブスクライブ パターンを処理します。これにより、ユーザーは 1 人以上のパブリッシャーにメッセージを 1 つ以上のトピックに送信させることができます。トピックごとに複数のサブスクライバーを設定することもできます。

永続ストレージを使用する Cloud Pub/Sub のパブリッシュ / サブスクライブ モデル

図 3: 永続ストレージを使用する Cloud Pub/Sub のパブリッシュ / サブスクライブ モデル

トピックの数と、トピックのグループ化を選択できます。トピックの数と、作成する Cloud Dataflow パイプラインの数には直接的な関連性があるため、論理的に関連しているイベントをグループ化するのが最適です。たとえば、パブリッシャーは、単一のトピックに対して複数のパブリッシャーを持つ、個々のモバイル デバイスまたはゲームサーバーにすることができます。必要なことは、HTTPS で、適切にフォーマット設定されたメッセージを認証して送信できることのみです。

メッセージ(この場合はプレーヤーのテレメトリー イベント)が Cloud Pub/Sub サービスによって受信されると、すべてのトピック サブスクリプションがそのメッセージを取得するまで、メッセージ ストアに永続的に保存されます。

Cloud Dataflow のストリーミング パイプライン

Cloud Dataflow では、簡単な方法でデータ処理パイプラインを記述する高レベル言語を使用できます。Cloud Dataflow マネージド サービスを使用してこれらのパイプラインを実行できます。Cloud Dataflow パイプラインはストリーミング モードで実行され、メッセージがサブスクリプションにより到着すると、Cloud Pub/Sub トピックからメッセージを取得します。次に、Cloud Dataflow は必要なすべての処理を行ってから、メッセージを BigQuery テーブルに追加します。

この処理は、簡単な要素的オペレーション形式で実行できます。たとえば、すべてのユーザー名を小文字にしたり、ユーザー名のテーブルをプレーヤー統計に結合するなど、要素を他のデータソースに結合したりすることができます。

BigQuery テーブル形式への JSON メッセージの変換

図 4: BigQuery テーブル形式への JSON メッセージの変換

Cloud Dataflow は、入力データのリアルタイム検証など、任意の数のデータ処理タスクを実行できます。たとえば、不正が検出されると、有効範囲外の最大ヒットポイントを持つプレーヤーを強調表示します。あるいは、イベント メッセージが適切に形式設定され、BigQuery スキーマと適合することを確認するなど、データ クレンジングにも使用されます。

図 4 の例では、ゲームサーバーからの元の JSON メッセージをマーシャリング解除し、BigQuery スキーマに変換します。重要なことは、この処置を実行するためにサーバーや仮想マシンを管理する必要がないことです。Cloud Dataflow がコンピューティング リソースを開始、実行、停止する作業を行い、パイプラインを並行処理します。また、ストリーミングとバッチ処理の両方に対して同じコードを再利用することもできます。

オープンソースの Cloud Dataflow SDK では、Cloud Dataflow プログラムの実行とは分離してパイプラインを実行できます。Cloud Dataflow プログラムによってパイプラインが作成され、この作成したコードによって、パイプライン ランナーが実行する一連のステップが生成されます。パイプライン ランナーには、GCP 上の Cloud Dataflow マネージド サービス、SparkFlink などのサードパーティ ランナー サービス、またはローカル環境でステップを直接実行するローカル パイプライン ランナーを使用できます。特に、ローカル パイプライン ランナーは開発とテストを行う際に有用です。

Cloud Dataflow は各要素が 1 回のみ処理されることを確認します。また、期間設定トリガー機能のメリットを活用すると、Cloud Dataflow に送信される時間(処理時間)ではなく、実際に発生した時間(イベント時間)に基づいてイベントを集約できます。モバイル機器のインターネット接続問題やバッテリーの消耗によって一部のメッセージがソースから遅延する可能性はありますが、そのような場合でも最終的にはユーザー セッションごとにイベントをグループ化する必要があります。Cloud Dataflow に組み込まれたセッション期間設定機能によって、これに対処できます。データ期間設定方法の詳しい説明については、The world beyond batch: Streaming 101 をご覧ください。

あるいは、イベントに Universally Unique Identifier(UUID)などの一意のセッション フィールドが含まれている場合、このキーを使用して関連するイベントをグループ化することもできます。使用する特定のシナリオに基づいて行うのが最適です。

BigQuery: 大規模なデータ解析用の完全に管理されたデータ ウェアハウス

BigQuery は 2 つの主要パーツで構成されています。その 1 つはストレージ システムであり、地理的冗長性と高可用性により、データの持続性を確保します。さらに、分析エンジンが配置されており、大量のデータセットに対して SQL のようなクエリを実行できます。BigQuery は、複数のテーブルを含めることができるデータセットにデータを編成します。BigQuery では、テーブルごとに定義されたスキーマが必要であり、前のセクションでの Cloud Dataflow の主なジョブは、内蔵 BigQuery コネクタを使用して JSON 形式の未処理イベントデータを BigQuery スキーマ構造に構造化することでした。

データが BigQuery テーブルにロードされると、対話式の SQL クエリをそれに対して実行し、価値のあるインテリジェンスを得ることができます。BigQuery は非常に大規模な状況に対応するように作成されており、短い応答時間でペタバイト規模のデータセットに対して集約クエリを実行できます。これは、対話式分析に適しています。

データ可視化ツール

Google データポータルを使用すると、BigQuery をはじめとする広範なデータソースにアクセスするインタラクティブなダッシュボードを作成して共有できます。

BigQuery は、TableauQlikView など、広く使用されているいくつかのサードパーティ製の BI と可視化ツールも統合します。Jupyter(以前の IPython)ノートブックに習熟している場合、Cloud Datalab サービスは BigQuery への組み込み接続も利用できます。最後に、BigQuery クエリを Google スプレッドシートMicrosoft Excel から直接実行できます。

バッチパターンを使用した一括処理

もう 1 つの主なパターンは、リアルタイムで処理する必要のない、大容量で制限付きのデータセットの定期的処理です。バッチ パイプラインはレポートの作成に使用されたり、リアルタイム ストリーム パイプラインを介して送られる最新情報を含む信頼性のある履歴データなど、両方の長所を生かすように、リアルタイム ソースと組み合わされたりすることがよくあります。

ゲームサーバーからのイベントとログのバッチ処理

図 5: ゲームサーバーからのイベントとログの一括処理

Cloud Storage は、容量の大きいファイルを保管する場所としておすすめです。これは、永続的で、可用性が高く、コスト効率の良いオブジェクト ストレージ サービスです。しかし、初めて Cloud Storage にデータを入れるにはどうすればよいでしょうか。これは、使用するデータソースによって異なります。次のいくつかのセクションでこのトピックについて説明します。オンプレミス、他のクラウド プロバイダ、GCP という 3 つの異なるデータソース シナリオについて学習します。

シナリオ 1: オンプレミス サーバーからファイルを転送する場合

多数の方法を使用して、オンプレミスのデータセンターからログファイルを安全に転送できます。最も一般的な方法は、オープンソースの gsutil コマンドライン ユーティリティを使用して、反復的なファイル転送を設定する方法です。gsutil コマンドにはいくつかの便利な機能が備わっています。たとえば、多数のファイルがある場合にマルチスレッドの並行アップロードを行ったり、ローカル ディレクトリの自動同期を行ったりできます。また、大容量のファイルに対して再開可能なアップロードを行うこともできます。非常に容量の大きいファイルの場合、ファイルをより小規模なパーツに分割し、並行してアップロードできます。これらの機能により、アップロード時間が短縮され、可能な限り多くのネットワーク接続を使用できるようになります。

インターネット帯域幅が不十分であるために適時にアップロードできない場合、ダイレクト ピアリングまたはキャリア ピアリングを使用して、GCP に直接接続できます。あるいは、物理的な媒体の送信を望む場合は、Offline Media Import/Export というサードパーティ サービスを使用して、媒体の受信とアップロードを代行させることもできます。

シナリオ 2: 他のクラウド プロバイダからファイルを転送する場合

一部のログファイルは、他のクラウド プロバイダを使用して保存される場合があります。おそらくそこでゲームサーバーを実行し、そのクラウド プロバイダのストレージ サービスにログを出力します。あるいは、デフォルトのストレージ ターゲットがあるサービスを使用します。たとえば、Amazon Cloudfront(Content Delivery Network サービス)は、そのログを Amazon S3 バケットに保存します。幸いなことに、Amazon S3 から Cloud Storage へのデータの移動は簡単です。

大量のファイルを毎日 Amazon S3 から Cloud Storage に転送する場合、Storage Transfer Service を使用して、Amazon S3 や HTTP/HTTPS サービスなどのソースからファイルを転送できます。転送が定期的に繰り返し行われるように設定できます。また、Storage Transfer Service ではいくつかの高度なオプションがサポートされています。このサービスは大手クラウド プロバイダ間の大規模ネットワーク帯域幅を活用し、高度な帯域幅最適化技術を使用して非常に高速な転送速度を実現します。

このサービスは、転送あたり 1 TB~10 TB 以上使用することをおすすめします。これにより、シナリオ 1 で述べたように、複数のサーバーで gsutil ツールを実行する場合の操作上のオーバーヘッドを軽減できます。より小規模な転送や、1 日に複数回データを移動する必要がある場合は、シナリオ 1 で述べた gsutil ツールを使用するほうがよい場合もあります。

シナリオ 3: データが GCP にすでに存在する場合

場合によっては、必要なデータがデフォルトで自動的に Cloud Storage に保存されていることもあります。たとえば、Google Play Store からのデータ(Reviews、Financial Reports、Installs、Crash、Application Not Responding(ANR)レポートなど)は、Google Play Developer アカウントに基づいて、Cloud Storage バケットで入手できます。このような場合、別のバケットにデータを移動する理由がなければ、エクスポート先の元のバケットにデータを保持できます。

非同期転送サービス パターン

長期的でスケーラブルな手法として、1 つ以上のキューとメッセージング機能を使用して、イベントまたはトリガーに基づいて転送を開始する非同期転送サービス パターンの実装があります。たとえば、新しいログファイルがディスクまたはソースファイル ストアに書き込まれると、メッセージがキューに送信され、ワーカーはそのオブジェクトを Cloud Storage に正常に転送し、正常に完了した場合にのみキューからメッセージを削除するというジョブを引き受けます。

代替バッチパターン: Cloud Storage から BigQuery への直接ロード

Cloud Storage と BigQuery の間に Cloud Dataflow を使用するのは必ずしも必要なことでしょうか。スキーマを指定し、ロードジョブを開始することで、Cloud Storage の JSON ファイルからファイルを直接ロードできます。あるいは、Cloud Storage バケットで CSV、JSON、または Cloud Datastore のバックアップ ファイルを直接クエリできます。これは開始時には容認可能な解決策になり得ますが、Cloud Dataflow を使用した場合は次のメリットがあります。

  • ストレージへの commit 前にデータを変換する。たとえば、BigQuery にロードする前に、異なるタイプのデータを別個のテーブルにグループ化してからデータを集約できます。これは、クエリ対象の行数を最小限に抑えることで、BigQuery コストを削減するのに役立つ可能性があります。リアルタイムのシナリオでは、Cloud Dataflow を使用して個々のセッション内、またはギルドやチームのような集団内のリーダーボードを計算できます。

  • Cloud Dataflow で作成されたストリーミングとバッチデータ パイプラインを相互に置き換えて使用する。たとえば、Cloud Pub/Sub から Cloud Storage など、データソースとデータシンクを変更します。同じコードが両方のシナリオで機能します。

  • データベース スキーマの観点から柔軟性を高める。たとえば、時間の経過とともにイベントに追加フィールドを追加してきた場合、追加の未処理 JSON データをスキーマの catch-all フィールドに追加して、BigQuery JSON クエリ機能を使用してそのフィールド内をクエリできます。その後、ソースイベントで厳密に異なるスキーマが必要であっても、複数の BigQuery テーブルに対してクエリを実行できます。これを図 6 に示します。

未処理 JSON で新しいイベント フィールドを取得するための追加列

図 6: 未処理 JSON で新しいイベント フィールドを取得するための追加列

リファレンス アーキテクチャに応じた操作上の考慮事項

パイプラインを確立して作成したら、パフォーマンスと、発生する可能性のある例外をモニタリングすることが重要です。Cloud Dataflow Monitoring のユーザー インターフェースでは、データ パイプライン ジョブを視覚的に表示することができ、主要なメトリックが示されます。図 7 は、このサンプル スクリーンショットです。

組み込み Cloud Dataflow モニタリング コンソール

図 7: 内蔵 Cloud Dataflow モニタリング コンソール

Cloud Dataflow コンソールは、パイプライン実行グラフに加え、各ステップで処理されているメッセージ数、予測されるシステムラグ、データ ウォーターマークなどの現在のパフォーマンス統計に関する情報を提供します。Cloud Dataflow は Stackdriver Logging サービスと統合されていますが、詳細については図 8 に、これに関するサンプル スクリーンショットを示します。

Cloud Dataflow と統合された Stackdriver Logging

図 8: Cloud Dataflow と統合されている Stackdriver Logging

その他の資料と追加リソース

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...