このチュートリアルでは、Memorystore for Redis を使用して Google Kubernetes Engine(GKE)で実行される ASP.NET ベースのリーダーボード アプリケーションを作成し、JavaScript ベースの別のサンプルゲームを使用してスコアを投稿および取得する方法について説明します。このドキュメントは、独自のリーダーボードをクラウドで運用することを必要とするゲーム デベロッパーを対象としています。
はじめに
リーダーボードは、マルチプレーヤー ゲームで一般的な機能です。リーダーボードは、プレーヤーのランキングをリアルタイムで表示します。これにより、プレーヤーのゲームへの関与を促進できます。プレーヤーのアクションをキャプチャし、スコアをリアルタイムでランク付けするには、Redis などのインメモリ データベースが最適です。
次の図は、リーダーボードのインフラストラクチャを示しています。
Google Cloud では、リーダーボードは VPC ネットワーク内の GKE クラスタと個別の Memorystore for Redis インスタンスで構成されます。
次の図は、このチュートリアルのアプリケーション アーキテクチャを示しています。クライアントはリーダーボード API を使用して、Google Cloud で実行されている Memorystore for Redis インスタンスに保持されているスコアを操作します。
リーダーボード API のメソッド
リーダーボード アプリケーションの API には、次のメソッドが含まれています。
PostScore(string playerName, double score)
: このメソッドは、指定されたプレーヤーのスコアをリーダーボードに投稿します。RetrieveScores(string centerKey, int offset, int numScores)
: このメソッドは一連のスコアをダウンロードします。centerKey
の値としてプレーヤー ID を渡すと、このメソッドは、指定されたプレーヤーのスコアの上下にあるスコアを返します。centerKey
の値を渡さないと、メソッドは上位 N 個の絶対スコアを返します。N はnumScores
に渡す値です。たとえば、上位 10 個のスコアを取得するには、RetrieveScores('', 0, 10)
を呼び出します。プレーヤーのスコアの上下 5 つのスコアを取得するには、RetrieveScores('player1', -5, 10)
を呼び出します。
このサンプルのコード リポジトリには、疑似ゲームと概念実証のリーダーボードの実装が含まれています。このチュートリアルでは、ゲームとリーダーボードをデプロイして、リーダーボード API が正しく機能し、インターネット経由でアクセスできることを検証します。
目標
- Memorystore for Redis インスタンスを作成する。
- このインスタンスにリクエストを送信するエンドポイントでヘッドレス サービスを作成する。
- リーダーボード アプリケーションを GKE にデプロイする。
- API 呼び出しを行うデプロイ済みのアプリケーションを使用して、リーダーボード機能を検証する。
費用
このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
準備
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。
-
Memorystore for Redis and Google Kubernetes Engine API を有効にします。
-
Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。
-
Memorystore for Redis and Google Kubernetes Engine API を有効にします。
環境の準備
このチュートリアルでは、Cloud Shell でコマンドを実行します。Cloud Shell では Google Cloud のコマンドラインにアクセスできるほか、Google Cloud で開発を行うために必要な Google Cloud CLI などのツールも利用できます。Cloud Shell の初期化には数分かかることがあります。
Cloud Shell を開きます。
デフォルトの Compute Engine ゾーンを Google Cloud リソースを作成するゾーンに設定します。このチュートリアルでは、
us-central1
リージョンのus-central1-a
ゾーンを使用します。export REGION=us-central1 export ZONE=us-central1-a gcloud config set compute/zone $ZONE
サンプルコードを含む GitHub リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/memstore-gaming-leaderboard.git
作成されたディレクトリのクローンに移動します。
cd memstore-gaming-leaderboard
テキスト エディタを使用して、
leaderboardapp/k8s/appdeploy.yaml
ファイルを開き、[YOUR_PROJECT_ID]
プレースホルダを Google Cloud プロジェクト ID に変更します。
Memorystore for Redis インスタンスの作成
このチュートリアル用に、テストとこのチュートリアルの対象範囲に適した Memorystore for Redis のベーシック ティア インスタンスを作成します。本番環境にデプロイする場合は、インスタンスの高可用性を確保するために、自動フェイルオーバーを備えた 99.9% SLA を提供するスタンダード ティア インスタンスをデプロイすることをおすすめします。スタンダード ティア インスタンスの詳細については、Memorystore for Redis の高可用性をご覧ください。
Cloud Shell で 1 GB の Memorystore for Redis インスタンスを作成します。
gcloud redis instances create cm-redis --size=1 \ --tier=basic \ --region=$REGION \ --zone=$ZONE
このコマンドが完了するまでに数分かかる場合があります。
アプリケーション コンテナ イメージの構築
このチュートリアルでは、GKE を使用して簡単なリーダーボード アプリケーションをデプロイします。Unity と C# はゲームで人気があるため、アプリケーション層では C# と ASP.NET フレームワークを使用します。
リーダーボード API を GKE クラスタにデプロイするには、まず Container Registry などのレジストリにアップロードする必要があります。
- クローンを作成した GitHub プロジェクトで
README.md
ファイルを開きます。 - 手順に従って Docker イメージを作成し、Container Registry にアップロードします。
次のセクションでクラスタを作成した後、このイメージを使用してリーダーボード アプリケーションをデプロイします。
GKE クラスタの作成または再利用
リーダーボード アプリケーションをデプロイする前に、有効なエイリアス IP 範囲を使用した GKE クラスタを作成する必要があります。エイリアス IP 範囲を使用した GKE クラスタがすでにある場合は、そのクラスタをこのチュートリアルで使用できます。既存のクラスタを使用する場合は、そのクラスタの認証情報を使用して kubectl
コマンドライン ツールを構成する手順も実施する必要があります。
クラスタを作成する場合は、2 つのノードを持つ
leaderboard
という名前のクラスタを作成します。gcloud container clusters create leaderboard --num-nodes=2 --enable-ip-alias
このコマンドが完了するまでには数分かかる場合があります。
クラスタが起動したら、稼働状態にあることを確認します。
gcloud container clusters list
leaderboard
という名前のエントリでステータスがRUNNING
になっていれば、クラスタが実行されています。
既存のクラスタの認証情報を構成する
このチュートリアルで既存の GKE クラスタを使用している場合は、そのクラスタの認証情報を使用して
kubeconfig
ファイルを構成します。name-of-existing-cluster にクラスタの名前を設定します。gcloud container clusters get-credentials name-of-existing-cluster
Memorystore for Redis インスタンスと Kubernetes Service のマッピング
Memorystore for Redis インスタンスの準備ができたら、アプリケーション階層が接続できるように GKE クラスタ内に Service を作成します。
Memorystore for Redis インスタンスが実行されていることを確認します。
gcloud redis instances list --region=$REGION
次のような出力が表示されます。
INSTANCE_NAME VERSION REGION TIER SIZE_GB HOST PORT NETWORK RESERVED_IP STATUS CREATE_TIME cm-redis REDIS_4_0 us-central1 STANDARD 1 10.0.0.3 6379 default 10.0.0.0/29 READY 2019-05-10T04:37:45
STATUS
列にREADY
と表示されている場合、インスタンスは実行中です。HOST
フィールドが空の場合、インスタンスは起動プロセスを完了していません。少し待ってから、redis instances list
コマンドを再度実行します。インスタンスの IP アドレスを環境変数に保存します。
export REDIS_IP=$(gcloud redis instances list --filter="name:cm-redis" --format="value(HOST)" \ --region=$REGION)
Redis 用の Kubernetes Service を作成します。
kubectl apply -f k8s/redis_headless_service.yaml
このサービスにはポッドセレクタがありません。これは、Kubernetes クラスタの外部にある IP アドレスを参照するためです。
前に取得した Redis IP アドレスを定義するエンドポイントを作成します。
sed "s|REDIS_IP|${REDIS_IP}|g" k8s/redis_endpoint.yaml | kubectl apply -f -
サービスとエンドポイントが正しく作成されたことを確認します。
kubectl get services/redis endpoints/redis
すべてが正常に機能している場合、次のような出力が表示され、Redis サービスと Redis エンドポイントのエントリが表示されます。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/redis ClusterIP 10.59.241.103 none 6379/TCP 5m NAME ENDPOINTS AGE endpoints/redis 10.0.0.3:6379 4m
Kubernetes Services とエンドポイントの詳細については、Google Cloud ブログの Kubernetes のベスト プラクティス: 外部サービスのマッピングをご覧ください。
リーダーボード アプリとサービスを Kubernetes にデプロイする
Redis インスタンスは、GKE クラスタにデプロイされたアプリケーションから到達可能になっています。リーダーボード アプリケーションをデプロイする準備が整いました。
- 先ほどクローンを作成した GitHub リポジトリのルートに格納されている
README.md
ファイルに記された手順に沿って進めます。
デプロイの検証
JavaScript で記述された疑似ゲーム アプリケーションを使用して、リーダーボード API を呼び出します。次のコード スニペットでは、プレーヤーがプレイを終了した後、疑似ゲームがスコアを投稿しています。
さらに、アプリケーションが API 呼び出しを行い、リーダーボード スコアを取得します。次のように、トップスコアまたはプレーヤー名の前後のスコアを取得します。
サンプル アプリケーションにアクセスするには:
次のコマンドを実行して、疑似ゲームの IP アドレスを取得します。
kubectl get ingress
出力は次のようになります。
NAME HOSTS ADDRESS PORTS AGE memstore-gaming-ingress * 34.102.192.4 80 43s
ブラウザで次の URL にアクセスします。ip_address_for_gke は疑似ゲームのアドレスです。
http://ip_address_for_gke.
このサンプルは単純ですが、基本的な API の使用方法を説明するには十分です。ユーザーのデバイスまたはマシンで実行されているゲーム クライアント アプリケーションからスコアを直接投稿または取得すると、このサンプルは Kubernetes Load Balancer オブジェクトに割り当てられたパブリック IP アドレスでリーダーボード API を呼び出します。このサンプル アプリケーションでは、リーダーボード API と JavaScript クライアントの両方が、前述の kubectl get ingress
コマンドを使用して取得した同一の IP アドレスにホストされています。
メソッドの実装方法
C# で記述されたリーダーボード アプリケーションは、Redis との通信に StackExchange.Redis ライブラリを使用します。次のコード スニペットは、Redis と StackExchange.Redis
ライブラリを使用して PostScore
と RetrieveScores
を実装する方法を示しています。
次のコード スニペットは、PostScore
メソッドを示しています。
次のコード スニペットは、RetrieveScores
メソッドを示しています。
サンプルゲームへの追加
リーダーボード API は REST 規則に従っており、サンプルとしてのみ提供されています。本番環境のゲームのリーダーボードを実行する場合は、検証済みのユーザーから取得したスコアのみを投稿できるように、認証フローを統合することをおすすめします。
現在、Memorystore for Redis ではプレーヤーのスコアを保持できません。したがって、アプリケーションで問題が発生すると、リーダーボードの情報が失われる可能性があります。ゲームに永続的なリーダーボードが必要な場合は、永続的なデータベースにリーダーボードのスコアを定期的にバックアップする必要があります。
クリーンアップ
このチュートリアルで使用したリソースに対して Google Cloud アカウントに課金されないようにするには、プロジェクトを削除します。
プロジェクトの削除
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
次のステップ
- 主な Memorystore for Redis のコンセプトを確認する。
- Google Play Games サービスのドキュメントで、リーダーボードのコンセプトを確認する。