これらのプラクティスを使用して、ライフサイクル全体にわたって信頼性が高く、スケーラブルで観測可能なデータを整理し、管理します。
データを整理する
データストアを少なくする
データストアはデータベースのテーブルに似た動作をします。少数の固定されたデータストアを使用し、その中でレコードをキーによって整理します。たとえば、各プレイヤーのプロファイルを個別のデータストアを作成するのではなく、1つの PlayerData データストアに保存します。
プレイヤーごとに1つまたは少数のキーを使用する
データが 4 MB オブジェクトサイズ制限 内に収まる場合は、各プレイヤーの永続データを1つのキーの下に保存します。たとえば、PlayerData データストア内で User_123456 のようなキーを使用します。このパターンはリクエストを減らし、関連する値を原子的に更新でき、ロールバックをより簡単に理解できるようにします。
プレイヤーのデータの異なる部分が異なるアクセスパターンを持っている場合や、キーごとのサイズまたはスループット制限に近づく場合は、レコードを少数の決定論的なキーに分割します。原子的に変更する必要があるデータは同じキーに保持します。
静的キーのパターンとプレフィックスを使用する
安定した識別子と静的パターンからキー名を構築します。たとえば、User_{UserId} のようにします。表示名や変更可能な他の値は使用しないでください。静的パターンは、サーバーやツール間でキーを予測可能にします。データストアの場合、これにより 自動的な忘れられる権利処理 がプレイヤーデータを特定できます。
関連するキーをグループ化するために プレフィックス を使用します。たとえば、複数のキャラクタープロファイルをサポートする体験では、User_123456/Profile/Warrior と User_123456/Profile/Mage を使用するかもしれません。次に、User_123456/Profile を ListKeysAsync() に渡して、そのプレイヤーのプロファイルをリストできます。
スコープ はデータストアを細分化する別の方法です。スコープは、そのデータストアインスタンス内のすべてのキーの前に文字列を追加し、デフォルトは global です。
データストアモジュールを評価する
サードパーティのデータストアモジュールは常に選択肢であり、多くの場合、ゼロからシステムを構築するよりも好まれることがあります。採用する前に、その所有権、メンテナンス状況、および機能セットを確認してください。モジュールなしでデータにアクセスし、移行する方法を理解します。
リクエストを減らし、分散させる
プレイヤーデータをメモリにバッファリングする
セッションの開始時にプレイヤーのデータをロードし、ゲームプレイのためにサーバーのローカルコピーを保持します。すべての変更に対してデータストアリクエストを送信するのではなく、ローカルコピーを更新します。プレイヤーが離れたとき、サーバーがシャットダウンするとき、購入処理などの重要なチェックポイントで定期的に保存します。リクエスト制限内に収まり、セッションロックの有効期限よりも短い定期的な保存間隔を選択します。たとえば、プレイヤーデータと購入サンプル は180秒を使用しています。
繰り返しリクエストをずらす
すべてのサーバーから同じスケジュールで繰り返しリクエストを開始しないでください。固定周波数のループを開始する前に、各サーバーまたはプレイヤーにランダムな初期オフセットを割り当てます。正確なリズムを必要としないポーリングや調整ループの場合は、各間隔に制限されたランダムなジッターを追加します。これらのパターンは、時間をかけてリクエストを分散させ、同期したトラフィックスパイクを減らします。
一時的な失敗を再試行する
リクエストを pcall() でラップし、一時的な失敗を指数バックオフで再試行します。サーバーが同時に再試行しないように、各遅延にランダムなジッターを追加します。遅延と試行回数に上限を設け、無効なリクエストやもはや有用な結果を提供できない操作によって引き起こされたエラーは再試行しないでください。
各キーのデータストア再試行を順番に処理します。新しいリクエストが成功した後に再試行される古いリクエストは、新しいデータを上書きする可能性があります。また、結果が不明な書き込みも考慮します:失敗した呼び出しはサーバーが成功した応答を受け取らなかったことを意味しますが、バックエンドは書き込みを完了している可能性があります。詳細については、データストアエラーコードと制限 および 再試行 を参照してください。
UpdateAsync を SetAsync より優先する
書き込みが現在の値に依存する場合や、複数のサーバーが同じキーに書き込む可能性がある場合は、UpdateAsync() を優先します。UpdateAsync() は書き込む前にコールバックに最新の値を読み込み、更新の損失を減らします。SetAsync() は最初に読み込まずにキーを上書きし、2つのサーバーが同時に書き込むと不整合を引き起こす可能性があります。
新しいキーを作成する場合や、前の値に依存しない値を置き換える場合は SetAsync() を使用します。2つのメソッドの比較については、Set vs update を参照してください。
ホットキーをシャード化する
各キーには 読み取りおよび書き込みスループット制限 があります。多くのサーバーが読み取るがめったに更新しない共有データの場合、同じレコードのコピーを含む複数のキーに読み取りを分散させます。このアプローチは、キーごとの読み取りスロットリング に対処するためのものであり、不必要なリクエストを減らした後にのみ使用します。書き込みスロットリングを解決したり、体験レベルやサーバーレベルのリクエスト予算を増やしたりすることはありません。
たとえば、体験全体の Admin Abuse イベントが Weather を変更することを考えてみてください。すべてのサーバーが単一の Weather キーから現在の天気を読み取る場合、そのキーは読み取りスループット制限に達する可能性がありますが、天気はめったに変わりません。代わりに、Weather_1、Weather_2、Weather_3 のような固定されたキーのセットの下にコピーを保存します。各サーバーは起動時にシャードを割り当て、たとえば DataModel.JobId を固定セットにハッシュ化することで、読み取りがキーに分散されます。各サーバーは自分に割り当てられたコピーのみを読み取ります。
共有キー、天気のコピーをポーリングする際には、最初の読み取りの前にランダムな初期遅延を追加し、その後の読み取りの間に制限されたランダムなジッターを追加します。サーバーが変更を観察する必要がある速さと読み取りスループット制限のバランスを取るポーリング間隔を選択します。すべてのサーバーが同時に読み取ることを避けてください。たとえば、共有イベント通知の直後などです。詳細については、繰り返しリクエストをずらす を参照してください。
天気が変わったときは、すべてのコピーを更新します。これらの書き込みはキー間で原子的ではないため、サーバーは一時的に異なる天気状態を読み取る可能性があります。レコードを複製すると書き込みが増え、一貫性や将来の移行がより複雑になります。すべてのリーダー間で原子的な更新が必要なデータや、すでにキーごとの読み取りスループット制限を下回っているデータにはこのアプローチを使用しないでください。
操作ワークフローを構築する
利用可能なツールを組み合わせて使用します:
- 観察する。 データストアの可観測性ダッシュボード を使用して、リクエスト、応答ステータス、スループット、ストレージを追跡します。重要なデータストアメトリクスのために カスタムアラート を設定し、チームが持続的な障害や予期しない成長に対応できるようにします。Creator Hub の通知は、ストレージが制限に近づくか超えたときに知らせ、ガイダンスやダッシュボードへのリンクを含みます。
- 検査する。 データストアマネージャー を使用して、データストア、キー、ストレージ使用量、および推定コストを調べます。体験が100以上のデータストアを持つ場合、データストアリストにはサイズとキーのカウントが表示されません。これらのメトリクスには Open Cloud または データストアバッチプロセッサ を使用します。
- 修正する。 個々のレコードにはデータストアマネージャーを使用します。繰り返し可能または大規模なワークフローには、Open Cloud データストア API または データストアバッチプロセッサ を使用します。
- 意図的にスケールする。 まず、不必要なストレージとリクエストを減らします。正当な使用がデフォルトのクォータを超える場合は、拡張サービス を評価します。
Open Cloud とゲームサーバーは、体験レベルのリクエスト予算を共有します。運用中の Open Cloud スクリプトのレート制限を行い、ライブトラフィックに干渉しないようにします。
データライフサイクルを管理する
すべての改訂のために新しいキーを作成するのではなく、データストアのバージョンを使用します。キーの最新バージョンのみがストレージ使用量にカウントされ、バージョンを使用すると以前の値を検査または復元できます。
一時的で急速に変化するデータには メモリストア を使用します。メモリストアのデータは自動的に期限切れになり、永続データストアのストレージには追加されません。
テストが終了したらテストデータを削除し、期限切れのイベントや退役した機能のデータを削除します。データストアを削除用にマークした後、復元できる30日間のバッファがあります。その30日後、Roblox はデータストアを永久に削除します。詳細については、データストアマネージャー を参照してください。
忘れられる権利処理を設定する
静的データストアおよびキーのパターンに従うプレイヤーデータのために 自動化された忘れられる権利 (RTBF) 処理 を設定します。自動化された RTBF は、Roblox が適格なリクエストを処理する際に削除テンプレートを適用するため、推奨されるワークフローです。
自動化された RTBF がデータスキーマをサポートしていない場合は、削除の権利ウェブフック を使用してカスタム削除ワークフローを実行します。いずれのワークフローも、すべての一致するプレイヤーデータを削除することを確認してください。