事前分割の概要

このドキュメントでは、データベースを事前分割する際に役立つ情報を提供します。

Spanner はデータベース スプリットを管理し、負荷とサイズの変化に応じてスケーリングします。分割と統合は、トラフィックに基づいて動的に実行されます。スプリットがより多くのトラフィックを受信すると、Spanner はそれをより小さい範囲に分割し、その結果得られたスプリットがインスタンス内の他の使用可能なリソースに再分散されます。スプリットが常に少ないトラフィックを受信している場合、Spanner はスプリットを統合します。

分割は即座に行われません。分割と再バランスがトラフィックに対応できない場合、分割によって使用可能なコンピューティング リソースとメモリリソースが使い果たされる可能性があります。このようなことが起こると、Spanner の作業スケジューラがキューに入れるリクエストがさらに増え、レイテンシが増加し、タイムアウトやトランザクションの中止につながる可能性があります。

データベースを事前に分割することで、予測可能なトラフィックの増加に備えることができます。分割ポイントを作成して、データベースを事前に分割できます。

次のシナリオでは、データベースの事前分割を検討してください。

  • 1 回限りの一括読み込みなど、大規模なデータセットを Spanner データベースの新しいテーブルとインデックスに初めて読み込んでいます。
  • 今後、既存の Spanner データベースでトラフィック負荷が増加することが予想されます。たとえば、製品のリリースや販売キャンペーンなど、トラフィックの増加が予想されるイベントをサポートする必要がある場合などです。

分割数を決める

ノードごとに 10 個の分割ポイントを作成することをおすすめします。Spanner は、小さいインスタンスでトラフィックをすばやく分割して調整できるため、小さいインスタンスを事前に分割する必要はありません。

分割点を決める

データベースの分割ポイントを決定する際は、次の点を考慮してください。

  • UUID やビット逆転シーケンスキーを使用する場合など、トラフィックがキー範囲全体に均等に分散されている場合は、ポスト トラフィック キースペースを均等に分割する分割ポイントを選択します。

  • トラフィックが既知のキー範囲に集中している場合は、それらのキー範囲を分割して分離します。

  • インデックスにトラフィックが発生することが予想される場合は、対応するインデックスで分割ポイントを使用します。

  • スプリット ポイントが親テーブルに追加されると、インターリーブされたテーブルは分割されます。インターリーブ テーブルでトラフィックが増加することが予想される場合は、対応するインターリーブ テーブルで分割ポイントを使用する必要があります。

  • 分割ポイントは、トラフィックの増加に比例してスキーマ オブジェクトに割り当てることができます。

分割点を決定するためのワークフロー例

データベースに次の DDL で定義されたテーブル構造があるとします。

CREATE TABLE UserInfo (
 UserId INT64 NOT NULL,
 Info BYTES(MAX),
) PRIMARY KEY (UserId);


CREATE TABLE UserLocationInfo (
 UserId INT64 NOT NULL,
 LocationId STRING(MAX) NOT NULL,
 ActivityData BYTES(MAX),
) PRIMARY KEY (UserId, LocationId), INTERLEAVE IN PARENT UserInfo ON DELETE CASCADE;


CREATE INDEX UsersByLocation ON UserLocationInfo(LocationId);

UserIdINT64 スペースでランダムに生成されたハッシュです。100 個の分割ポイントを追加して、UserInfo テーブルとそのインターリーブ テーブルに予想されるトラフィックの増加を均等に分散する必要があります。分割ポイントは均等に分散されているため、各分割ポイント間の行数(offset)を確認する必要があります。

offset = UserId 範囲の最大値 / 99

次に、テーブル UserInfo の分割ポイントは、UserId の最初の行(UserId_first)から決定されます。分割ポイントの N 番目を決定するには、次の計算を使用します。

分割点 N: UserId_first + (offset * (N-1))

たとえば、最初の分割ポイントは UserId_first +(offset * 0)、3 番目の分割ポイントは UserId_first +(offset * 2)です。

UserLocationInfo テーブルは UserInfo テーブルのインターリーブ テーブルであるため、UserId 境界で分割されます。UserLocationInfo テーブルの LocationId 列に分割ポイントを作成することもできます。

LocationId$COUNTRY_$STATE_$CITY_$BLOCK_$NUMBER 形式に従います(例: US_CA_SVL_MTL_1100_7)。

UserId の場合、LocationId 文字列の接頭辞に基づいて分割を決定し、UserIdUserLocationInfo テーブルを 3 つの異なる国に 3 つの異なる分割で配置できます。

  • 分割点 1: (1000、「CN」)
  • 分割点 2: (1000、「FR」)
  • 分割点 3: (1000、「US」)

新しい分割ポイントは接頭辞のみを使用して追加できます。列またはインデックスの指定された形式と一致する必要はありません。この例では、分割ポイントは LocationId の指定された形式と一致しておらず、接頭辞として $COUNTRY のみを使用しています。

UsersByLocation インデックスを分割する場合は、分割ポイントを LocationId 列に均等に分散するか、トラフィック増加が予想される LocationId 列の値をいくつか分離します。

  • 分割点 1: 「CN」
  • 分割ポイント 2: 「US」
  • 分割ポイント 3: 「US_NYC」

トラフィックの増加がさらに大きいロケーションには、インデックスに登録されたテーブルのキーパーツを使用してインデックスをさらに分割できます。たとえば、CN のロケーションでトラフィックが増加すると予想される場合は、次の分割ポイントを導入できます。

  • 分割点 1: 「CN」と TableKey: (1000、「CN」)
  • 分割点 2: 「CN」と TableKey: (2000、「CN」)
  • 分割点 3: 「CN」と TableKey: (3000、「CN」)

分割点の有効期限

分割ポイントごとに有効期限を設定できます。ユースケースに応じて、予想されるトラフィックの増加が収束した後に分割ポイントが期限切れになるように設定します。

デフォルトの有効期限は、分割の作成または更新から 10 日間です。指定できる有効期限は、分割の作成または更新から 30 日間です。

分割が期限切れになると、Spanner が分割の管理を引き継ぎ、分割を表示できなくなります。Spanner は、トラフィックによっては分割を統合することがあります。

有効期限が切れる前に、分割ポイントの有効期限を更新することもできます。たとえば、トラフィックの増加が収まっていない場合は、分割の有効期限を延長できます。分割ポイントが不要になった場合は、すぐに期限切れになるように設定できます。分割ポイントの有効期限を設定する方法については、分割ポイントを期限切れにする方法をご覧ください。

データベースを事前分割した結果

分割ポイントを追加すると、次のような結果が得られます。

  • レイテンシの変化: 分割ポイントを追加することは、データベースでのトラフィックの増加をシミュレートする方法です。データベースのスプリット数が多いと、トランザクション パーティシパントとクエリ分割が増えるため、読み取りと書き込みのレイテンシが永続的に増加する可能性があります。また、読み取りまたは書き込みリクエストあたりのコンピューティングとクエリの使用量も増加します。

  • 分割ポイントの効果: 追加された分割ポイントが有益かどうかを判断するには、レイテンシ プロファイルで最小限の変更を、キー ビジュアライザーでホットスポットがないかをモニタリングします。ホットスポットに気付いた場合は、分割ポイントをすぐに期限切れにして、新しい分割ポイントを作成できます。分割ポイントの有効期限の詳細については、分割ポイントを期限切れにする方法をご覧ください。分割の追加の次の反復処理で、分割の数を減らしてレイテンシ プロファイルを確認することを検討してください。

  • トラフィック増加後の分割ポイントの動作: 追加された分割ポイントは、トラフィック増加が安定した後に削除する必要があります。分割分布が、負荷増加前の状態に収束しない場合があります。トラフィックの変化とトラフィックのサポートに必要な分割により、データベースが異なるレイテンシ プロファイルに落ち着く可能性があります。

使用例

ゲーム会社のデータベース管理者として、新しいゲームのリリースでトラフィックの増加を予測しているとします。空の新しいテーブルでトラフィックが予想されます。

トラフィックが到着したときにサービスが停止されないようにし、レイテンシやエラー率に顕著な影響がないようにする必要があります。

このユースケースでは、次の大まかな事前分割手法を検討してください。

  1. 増加したトラフィックをサポートするためにインスタンスに必要なノード数を特定します。ノード数を確認する方法については、パフォーマンスの概要をご覧ください。オートスケーラーを使用している場合は、最大上限パラメータを特定したノード数に設定します。また、最小制限パラメータを(特定したノード数 / 5)に設定します。

  2. トラフィック量が最も多く、分割ポイントの使用によって最もメリットが得られるテーブルとインデックスを特定します。現在のデータを分析し、カスタム分割ポイントと均等に分散された分割ポイントのどちらを使用するかを選択します。

  3. トラフィックの増加が予想される 7 日前から 12 時間前までに分割ポイントを作成します。

  4. 分割が作成されたことを確認します。インスタンスで作成された分割ポイントを表示するには、分割ポイントを表示するをご覧ください。

注意点

分割ポイントを作成する際は、次の注意事項を考慮してください。

  • テーブル、インデックス、データベースの削除: テーブル、インデックス、データベースを削除する前に、対応する追加された分割ポイントがすべて期限切れになっていることを確認する必要があります。これを行うには、分割の有効期限を現在の時刻に設定します。これは、インスタンス レベルの割り当てを再利用するために必要です。分割ポイントの有効期限の詳細については、分割ポイントを期限切れにする方法をご覧ください。

  • データベースのバックアップと復元: 追加された分割はバックアップされません。復元されたデータベースにスプリットを作成する必要があります。

  • 非対称自動スケーリング: 非対称自動スケーリングを使用している場合、分割ポイント数を決定するために使用されるノード数は、すべてのリージョンの最小ノード数です。

  • ストレージ使用量指標の一時的な増加: 分割ポイントを追加すると、Spanner が圧縮を完了するまで、データベース ストレージの合計指標が一時的に増加します。詳細については、ストレージ使用率をご覧ください。これは、既存のキー範囲がさらに分割された場合にのみ発生し、新しいキー範囲が分割された場合には発生しません。

  • 分割ポイントは、トラフィックの増加が予想される 7 日前から 12 時間前までに作成する必要があります。

事前分割の上限

データベースを事前に分割する場合は、次の制限があります。

  • 検索インデックスを事前に分割することはできません。ベーステーブルを事前に分割するだけで済みます。詳細については、検索インデックスのシャーディングをご覧ください。

  • ベクトル インデックスを事前に分割することはできません。ベクトル インデックスの詳細については、ベクトル インデックスをご覧ください。

  • 分割ポイントの割り当てについては、割り当てと上限をご覧ください。

次のステップ