非リレーショナル ランキングのリファレンス アーキテクチャ

小規模向けの単純なランキング

S単純なランキングの外観

アーキテクチャの図

S非リレーショナル データベースを使用した小規模向けの単純なランキング

実装の詳細

ソース コードを含むこの完全なチュートリアルでは、Azure Cache for Redis を別のデータベースと共に使用するランキングを実装して、データ スループットを向上し、データベースの負荷を軽減する方法を学習できます。

Azure Cache for Redis を永続データベースのバックエンドのキャッシュ レイヤーとして使用するキャッシュ アサイド パターンを利用します。 書き込みを行うときは常に、永続データベースと Azure Cache for Redis の両方にデータを書き込みます。 読み取るときは常に、最初にキャッシュからデータを読み取ります。ミスが発生した (データは一定期間が過ぎると期限切れになるため、データがキャッシュ内に残っていない) 場合は、永続データベースからデータを読み取り、その直後にキャッシュに書き込みます。 キャッシュがヒットした場合は、キャッシュからデータを読み取ります。

このサンプルでは、.NET の抽象化レイヤーである Entity Framework を使用してデータ オブジェクト間の関係をモデル化し、表現しています。 それを使用して、プログラミング モデルの観点から簡単に言うと一連のオブジェクトを取得し、それらのオブジェクトにプロパティを設定します。すると、Entity Framework によってすべての操作が SQL 操作にマップされます。

ステップ バイ ステップの手順は次のようになります。

  1. クライアント デバイスは、上のアーキテクチャ図に示されているように Azure Web アプリ (Web サービス) に接続し、新しいプレイヤーのレコードをアップロードします。 別の方法として、Web サービスの代わりにたとえばそれぞれが特定のタスクを実行する Azure Functions を使用したり、ロード バランサーと仮想マシンを使用することもできます。
  2. Azure Web アプリは、新しいレコードをアップロードするアクションを受け取り、キャッシュ アサイド パターンに従って、それを最初に永続データベース (ここでは Azure SQL データベース) に書き込みます。
  3. その後、引き続きキャッシュ アサイド パターンに従って、同じレコードが Azure Cache for Redis に保存されます。
  4. 別のプレイヤーが特定のランキングの表示を要求したので、Azure Web アプリ (Web サービス) に接続します。
  5. Azure Web アプリは、特定のランキングからレコードを取得するアクションを受け取ります。 最初に、Azure Cache for Redis からの読み取りを試みます。 見つかった場合は (ヒット)、単純にその情報をクライアント デバイスに返します。
  6. Azure Cache for Redis からレコードを読み取ろうとしたときにミスが発生した (データは一定期間が過ぎると期限切れになるため、データがキャッシュ内に残っていない) 場合、Azure Web アプリは永続データベース (ここでは Azure SQL データベース) からレコードを読み取ります。
  7. 永続データベースから取得されたレコードが Azure Cache for Redis に保存され、最終的にクライアント デバイスに送信されます。

代替手段

Azure SQL Database の代わりに、たとえば Azure Database for MySQL などの他のデータベースも使用できます。

大規模向けの高度なランキング

アーキテクチャの図

非リレーショナル データベース ランキングのユース ケース

アーキテクチャのサービス

この実装では、Azure Cosmos DB SDK ではなく Azure Function を使用してデータを書き込みます。 より細かな制御とデバッグが必要な場合は、アプリ サービスと Change Processor SDK を利用できます。

アーキテクチャの考慮事項

ゲームのランキングを設計する際には、さまざまな設計上の考慮事項と選択肢があります。

マスター コレクション、パーティション、パーティション キー

先へ進む前に、Azure Cosmos DB のいくつかの基本的な側面について説明しておきましょう。

パーティション分割は、Azure Cosmos DB でデータベース内の個々のコンテナーをスケーリングするために使用される手法です。 コンテナー内の項目は、論理パーティションと呼ばれる特定のサブセットに分割されます。

論理パーティションは、各項目に関連付けられているパーティション キー プロパティの値に基づいて作成される、コンテナー内の項目の特定のサブセットです。

論理パーティション内の項目は、論理パーティション内のすべての項目によって共有されるパーティション キー値で識別されます。 たとえば、複数のドキュメントを保持しているコンテナーがあり、ドキュメントごとに 1 つの UserID プロパティがあるとします。 UserID がコンテナー内の項目のパーティション キーとして機能し、1000 個の一意の UserID 値がある場合、そのコンテナーには 1000 個の論理パーティションが作成されます。

コンテナー内の各項目には、その項目の論理パーティションを決定するパーティション キーがあり、各項目には項目 ID (論理パーティション内で一意) もあります。 項目のインデックスにより、項目が一意に識別されます。これはパーティション キーと項目 ID を組み合わせて作成されます。

パーティションキーを定義する際は、次の 3 つの重要な点を考慮する必要があります。

  1. 各コレクションは多数のパーティション キーを持つことができますが、パーティション キーあたりのサイズは 10 GB までに制限されています。
  2. パーティション キーは更新できません。 A_B_C のようなパーティションキーを作成した場合、後で A_B_C_D に更新することはできません。 ただし、新しいキーを作成してデータを移行することは可能です。
  3. 目標は、すべてのパーティションにわたって均等にワークロードを分散し、ホット スポットを回避することです。

ランキングのためのパーティション キーを選択する方法の詳細については、「パーティション キーの選択」を参照してください。

このランキングのリファレンス アーキテクチャの実装では、グローバル ランキングの一般的なコレクション (すべてのエントリを格納するマスター コレクション) と、値の各組み合わせに対するパーティション キーを使用します。

このユース ケースでは、プレイヤーのスコアは platform と level の 2 つの変数に基づいてランク付けされlevel_system がパーティション キーとして使用されます。

具体的な例を示すと、このリファレンス アーキテクチャと実装を利用しているゲームが Xbox と PlayStation の両方のプラットフォームで起動され、2 つのレベル (1 と 2) しかない場合、最終的に次のコレクションとパーティションが Azure Cosmos DB に生成されます。

  • マスター コレクション
  • パーティション 1 (all_all)
  • パーティション 2 (xbox_all)
  • パーティション 3 (ps4_all)
  • パーティション 4 (all_level1)
  • パーティション 5 (all_level2)
  • パーティション 6 (xbox_level1)
  • パーティション 7 (ps4_level1)
  • パーティション 8 (xbox_level2)
  • パーティション 9 (ps4_level2)

スキーマは次のとおりです。

{
    "id": "1",
    "platform": "Xbox Live",
    "level": 3,
    "character": "Damian",
    "name": "Brian",  //platform gamertag
    "xp": 12345, // stat 1
    "quests": 12 //stat 2
}

明確化のためだけに、もう少し複雑な、レーシング ゲームの 3 つの変数 level (Laguna Seca と Monza)、choice (fast class と slow class)、stat (fastest lap と power ups picked up) を使用するシナリオではどうなるかを示します。 使用されるパーティション キー構造は level_choice_stat で、ユーザーがレコードをアップロードすると次の組み合わせが生成されます。

  • マスター コレクション
  • パーティション 1 (lagunaseca_fastclass_fastestlap) [000]
  • パーティション 2 (lagunaseca_fastclass_powerupspicked) [001]
  • パーティション 3 (lagunaseca_slowclass_fastestlap) [010]
  • パーティション 4 (lagunaseca_slowclass_powerupspicked) [011]
  • パーティション 5 (monza_fastclass_fastestlap) [100]
  • パーティション 6 (monza_fastclass_powerupspicked) [101]
  • パーティション 7 (monza_slowclass_fastestlap) [110]
  • パーティション 8 (monza_slowclass_powerupspicked) [111]

このシナリオでは、最初のプレイヤーが fast class (choice) に属する車両を使用してトラック Monza (level) を走行した場合、Azure Cosmos DB に格納される情報は次のようになります。

グローバル ランキング コレクション (leaderboards_all_data) { userID: "XYZ", stat: "fastestlap", choice: "fastclass", level: "monza", value: "123" } { userID: "XYZ", stat: "powerupspicked", choice: "fastclass", level: "monza", value: "1" }
パーティション 5 (monza_fastclass_fastestlap) { userID: "XYZ", stat: "fastestlap", choice: "fastclass", level: "monza", value: "123" }
パーティション 6 (monza_fastclass_powerupspicked) { userID: "XYZ", stat: "powerupspicked", choice: "fastclass", level: "monza", value: "1" }

カスケード書き込みパターン

マスター コレクションと 1 つ以上のサブテーブルに情報を書き込むことが必要になるため、特に関連する変数 (例: iOS、Android とモバイル。 ここで、モバイルは iOS と Android の両方のユーザーからのレコードを表示するフィルター) がある場合は、複数の書き込み操作を行うのではなく、Azure Cosmos DB の変更フィードにトリクル効果で処理を実行させることがベスト プラクティスとなります。これにより、1 つの書き込みしか実際に完了しなかった場合に発生する可能性がある不整合を回避できます。

パーティション キーの更新

既に説明したように、既存のパーティション キーは更新できませんが、新しいパーティション キーを追加することはできます。

先ほどの 2 つの変数の例に戻って、ユーザーがプレイする難易度の設定 (易しい、普通、難しい) に応じてデータを分割するために、変数をもう 1 つ追加する必要が生じたとしましょう。 そのためには、古いパーティション キー level_systemlevel_system_difficulty にアップグレードする必要があります。 既存のパーティション キーを更新できないという制限を回避するために、次の手順を実行する移行ツールが用意されています。

  1. 変更フィードを使用してコレクション全体をドレインします。
  2. 別のパーティション キーを使用してデータを再取り込みします。

Azure Cosmos DB の 1 秒あたりの要求ユニット

Azure Cosmos DB コレクションの課金方法、要求ユニットの数の追跡方法、要求に関する経験則については、一般的なガイドラインのドキュメントを参照してください。

デプロイ テンプレート

Azure サービスの名前付け規則と制限事項をまとめた記事が含まれる一般的なガイドライン ドキュメントを参照してください。

最適化に関する考慮事項

Cosmos DB のコストの最適化に関しては、以下のリソースが役立ちます。

その他の使用可能な機能

プッシュ通知のサポートの追加

プレイヤーが使用しているプラットフォームによっては、たとえばフレンドにスコアを抜かれたことをプレイヤーに知らせたい場合がありますが、これは Azure Cosmos DB の変更フィードAzure Notification Hubs サービスを利用して実現できます。

プッシュ通知のサポートのアーキテクチャ

その他のリソースとサンプル

MongoDB API を使用する Functions と Cosmos DB

ゲーム ランキング (スコア) を格納し、HTTP(s) メソッド/操作を使用してそれを公開する、Azure Functions でホストされ、Mongo API を使用する Azure Cosmos DB によってサポートされるゲーム ランキング API を設定します。 この API サービスをゲームで使用して、新しいスコアの投稿、トップ スコアの取得、最新スコアの確認などができます。

価格設定

Azure サブスクリプションをお持ちでない場合は、無料アカウント を作成して 12 か月間の無料サービスの利用を開始できます。 それらのサービスの制限を超えない限り、Azure 無料アカウントで無償で提供されているサービスに対して料金が発生することはありません。 Azure Portal または使用状況ファイルを通じて使用状況を確認する方法について説明します。

これらのリファレンス アーキテクチャの実行中に使用される Azure サービスのコストはユーザーが負担し、その合計は分析パイプラインで実行されるイベントの数によって異なります。 リファレンス アーキテクチャで使用されていた各サービスの価格は、Web ページで確認ください。

また、Azure の料金計算ツールを使用して、使用する予定の Azure サービスのコストを構成および見積もることもできます。