Spanner

Cloud Spanner 用 TTL を使用した不要データの自動クリーンアップ

#spanner

※この投稿は米国時間 2021 年 11 月 6 日に、Google Cloud blog に投稿されたものの抄訳です。

Google Cloud は、このたび Cloud Spanner の有効期間(TTL)の一般提供を開始しました。TTL をより広範なエンタープライズ管理機能群の一部として使用すると、データベース管理者はポリシーを設定し、Spanner のテーブルから短期的にしか利用されない、一時的な、または不要なデータを定期的に削除できます。不要データを削除することで、以下を行いやすくなります。

  • ストレージ費用とバックアップ費用を削減する。

  • 一部のクエリをスキャンする場合のデータベースの行数を削減することで、クエリのパフォーマンス向上を図る。

  • 特定種類のデータの保持時間を制限する法規または業界ガイドラインを遵守する。

TTL は、定期的なクリーンアップ作業に最適です。1 回限りのクリーンアップ スクリプトの代わりに使用できるよう設計されており、運用上のオーバーヘッドや手作業による誤りが発生する機会を減らしてくれます。TTL は、バックグラウンドで継続的に動作し、期限切れのデータを一定の時刻に定期的に一括削除します。現在 Spanner をご利用のすべてのお客様は、追加費用なしで本日からご利用できます。

例: リアルタイムでのルート計画

TTL が費用の削減と複雑さの軽減にどのように役立つかをより深く理解するため、架空の配送スケジューリング アプリケーションの例を見てみましょう。ユーザーが配送を依頼すると、アプリは複数の経路オプションを割り出し、たとえば、同じ経路の荷物をまとめるなど、最適化アルゴリズムに基づいて最適な経路を選択します。

アプリケーションのこの側面の Spanner スキーマを簡単に表すとは、以下のようなものになると考えられます。

  CREATE TABLE CalculatedRoutes (
  PartyId INT64,
  RouteId INT64,
  CreatedAt TIMESTAMP NOT NULL,
  RouteStatus STRING(10) NOT NULL
) PRIMARY KEY (PartyId, RouteId);
 
CREATE TABLE RouteSteps (
  PartyId INT64,
  RouteId INT64,
  Step INT64,
  Waypoint STRING(MAX)
) PRIMARY KEY (PartyId, RouteId, Step),
INTERLEAVE IN PARENT CalculatedRoutes ON DELETE CASCADE;

CalculatedRoutes には、任意の配送について取り得る選択肢が保持されます。RouteSteps テーブルには、任意の選択肢に関連するターンバイターン方式の経路案内が格納されます。割り出された各経路には、多くのステップがあります。RouteSteps テーブルは、関連する CalculatedRoutes にインターリーブされます。テーブルのインターリーブは、たとえばターンバイターン方式で経路を表示したり、最適化アルゴリズムで経路の合計スコアを計算するため、一緒にアクセスされることが多い 1 対多の関連データのパフォーマンス最適化に役立ちます。

一致アルゴリズムの品質と速度は、全体的なユーザー エクスペリエンス向上の鍵となります。リアルタイムでの最適化プロセスにおいて、このデータが高可用性と整合性を持つことが非常に重要となります。Spanner は、このような読み書き可能で双方向性のあるワークロードに対応する規模を備えており、最大 99.999% の可用性とグローバルな整合性を保証します。経路が確定すると、他の経路は必要なくなります。この架空のアプリケーションが大量の配達物を扱う上で、このような短命なデータは邪魔になります。Spanner は、アプリケーションが TTL を使用して行レベルの削除ポリシーを設定し、データをより適切に管理するための機能を備えています。

TTL を使用したフルマネージド型バックグラウンド クリーンアップ

Spanner では現在、SQL での DELETEパーティションごとの削除によるデータ削除が可能です。これらは、トランザクションの境界を正確に管理する必要がある場合や、優先度の高いリソースを割り当てて処理時間を最小限に抑えたい場合のデータ削除に役立ちます。TTL は、システム全体への影響を最小限に抑えるフルマネージド型のバックグラウンド プロセスにより、このデータ削除を補完します。手動でのパーティショニング、バッチ処理、再試行を行う必要がありません。TTL は、いったん設定すれば、後のことを気にする必要はありません。

Spanner のこの新しい手法には、以下のとおり複数の重要な利点があります。

  • 簡単さ: 行削除ポリシーは宣言型です。行をどのように削除するかではなく、行の削除条件を Spanner に伝えます。TTL ロジックはスキーマで一元的に定義されるため、管理対象のテーブルと一緒に管理しやすく、論理的決断がより容易に下せます。重要なクリーンアップ ロジックを理解するために複雑なアプリケーション コードや外部スクリプトを掘り下げる必要はありません。

  • スケーラビリティ: TTL は、データベースに合わせてスケーリングされます。Spanner は、不要となった行のスキャンと削除をインスタンス内の全ノードに対しシームレスに実行します。TTL は、データベースの拡大に伴い、追加の介入なしに動的に調整されます。

  • 予測性: TTL は、データベースの他のワークロードへの影響を最小限に抑えるよう設計されています。TTL のスイーパー プロセスは、優先度の低いタスクとして、バックグラウンドで動作します。TTL のスイーパー プロセスは、オーバーヘッドが最小限となるよう、カスタムクエリで可能なプロセスよりも効率的に、時間と利用可能なインスタンス リソースにまたがり作業を分散させます。

  • 監視可能性: TTL は Cloud Monitoring に統合されています。開発者が別途パイプの構築や維持を行うことなく、残りのスタックと一緒に進捗や警告をエンドツーエンドで把握できます。

行削除ポリシーの構成

実際の動作を確認するために、例に挙げた 1 回限りの割り出し経路を 9 日後に自動的に削除するよう Spanner を構成してみましょう。

まず、スキーマ定義の CalculatedRoutes テーブルに行削除ポリシーを追加します。他のスキーマの変更と同様に、行削除ポリシーの設定や変更には、そのための権限が必要です。

  ALTER TABLE CalculatedRoutes 
  ADD ROW DELETION POLICY (OLDER_THAN(CreatedAt, INTERVAL 9 DAY));

行削除ポリシーを設定することで、テーブルの行がいつ自動削除の対象となるかが Spanner に伝わります。行削除ポリシーは、たとえば、ある行については「作成時刻 + 9 日」とするように、タイムスタンプと期間で設定します。行削除ポリシーのタイムスタンプ列は、Spanner に組み込まれた commit タイムスタンプを使用し、TrueTime を使用して正確な追跡を行えます。

上記のインターリーブされた子 RouteSteps テーブルに ON DELETE CASCADE を指定したため、これらの関連する行は、親経路と同じトランザクションで自動的に削除されます。これにより、複数のトランザクションで経路が一括削除されても、特定の経路とそのステップの参照整合性が確保されます。

スキーマを更新すると、TTL は設定可能なすべてのポリシーに対応するためにバックグラウンド スキャンを自動的に調整し、次のサイクルで変更点を取り込みます。

有効期間のライフサイクル

行削除ポリシーに従って行を削除できるようになっても、その行が直ちに照会できなくなるわけではありません。バックグラウンドのシステム プロセスである「スイーパー」は、削除対象となる行を毎日確認し、効率性確保のためにデータが内部に保存されている場所に近い場所で実際の削除をバッチ単位で行います。スイーパーは、バッチサイズを自動的に調整し、一時的なエラーの発生時には再試行を行います。たとえば、関連するインデックスまたはインターリーブされた子プロセスにより、トランザクションがミューテーション上限を超える場合には、バッチサイズを縮小します。再試行を行っても、通常は 3 日以内に行が削除され、その結果、照会できなくなります。

1 TTL for Cloud Spanner.jpg
バックグラウンド スウィーパーは、対象となる行を毎日バッチ単位で削除し、必要に応じて再試行し、通常は 3 日以内に削除します

別のプロセスにより、削除された行の保存容量を回収する作業が通常は 7 日以内に行われます。

より高度な失効ロジック

単純にタイムスタンプと期間を設定するだけで多くの一般的なシナリオに対応できますが、より高度なロジックが必要な場合はどうしたらよいでしょうか。たとえば、この架空の配送物流計画アプリに、訴訟のための記録保持の対象となっているデータを削除しないという追加要件があったとしたら、どうしたらよいでしょうか。

これを実現するには、ビジネス ロジックを取り込むために生成された列を使用し、そこに行削除ポリシーを接続します。生成された列と行削除ポリシーの組み合わせにより、過度に複雑で矛盾する可能性のあるルールを作成することなく、より高度なロジックに対応する柔軟な方法を取ることができます。

  ALTER TABLE CalculatedRoutes
  ADD COLUMN LegalHoldUntil TIMESTAMP;
 
ALTER TABLE CalculatedRoutes
  ADD COLUMN ExpiredDate TIMESTAMP AS (
    GREATEST(
COALESCE(LegalHoldUntil, CreatedAt), 
TIMESTAMP_ADD(CreatedAt, INTERVAL 9 DAY)))
  STORED;
 
ALTER TABLE CalculatedRoutes 
  REPLACE ROW DELETION POLICY (OLDER_THAN(ExpiredDate, INTERVAL 0 DAY));

上の例では、行削除ポリシーを、生成された ExpiredDate 列に接続された新しいポリシーに置き換えています。先ほどと同様に、生成された列は TIMESTAMP である必要があります。有効期限は SQL ステートメントを使用して、訴訟のための記録保持の日または元のポリシーである「作成日 + 9 日」のうち大きい方を計算します。Spanner は、生成された列とその列が依存する列が常に整合性を保つことを保証します。

行削除ポリシーの INTERVAL 0 DAY は、指定されたタイムスタンプで行が直ちに削除対象となることを示しています。割り出されたポリシーにより、条件付きの期間ロジックが生成された列定義に移動されます。

進捗状況の監視

古い経路の自動クリーンアップを構成したので、Cloud Monitoring と組み込みシステム テーブルを使用して、行のクリーンアップの進捗状況を確認し、データ廃棄の要件を満たしているかを確認して、問題があればそれを特定できるようになりました。

deleted_rows_count という指標は、TTL によってクリーンアップされた行のスループットを追跡します。このスループットは、行が 1 日のうちで異なる時間に失効したり、スイーパーが Spanner インスタンスのノードに分散されたスプリット、すなわちデータの個々のスライスに対して並列的に削除を実行したりすることで、おのずと変動します。

2 TTL for Cloud Spanner.jpg
TTL のスループットは、行の有効期限が切れたり、行がクリーンアップされることで、時間とともに変動します

スイーパーは、Spanner インスタンスの全体的な負荷を最小限に抑えるために、各スプリットに対し異なる時間に実行されます。

processed_watermark_age 指標は、削除対象となる行のスキャンが最後に無事完了してからの時間を追跡します。TTL バックグラウンド スイーパーが削除対象データのスキャンに必要なリソースを持っている場合、以下のように 1 日から 2 日の間にノコギリの歯のような規則的パターンが見られます。リソースが適切に確保されているインスタンスでは、削除対象の行は通常、3 日以内に削除されます。

3 TTL for Cloud Spanner.jpg

TTL 処理に予想以上の時間がかかった場合や、TTL に再試行不可のエラーが発生した場合の通知を構成できます。今回の配車スケジューリング アプリケーションでは、processed_watermark_age が 3 日を超えた場合にアラートが発出されるよう設定します。

4 TTL for Cloud Spanner.jpg

Cloud Monitoring における TTL ウォーターマーク経過時間経過時の通知の作成

管理者は、組み込みのシステム テーブルを照会して、TTL クリーンアップの状況をより正確に理解することもできます。たとえば、クリーンアップが失敗したテーブルをすべて列挙し、トランザクションの制約などにより自動削除できなかった最も古い行のタイムスタンプを確認できます。

5 TTL for Cloud Spanner.jpg
TTL ウォーターマーク経過時間が 3 日を超えた場合の警告しきい値の設定(259,200,000 ミリ秒 = 3 時間 × 60 分 × 60 秒 × 1,000 ミリ秒)
  SELECT TABLE_NAME, UNDELETABLE_ROWS, MIN_UNDELETABLE_TIMESTAMP 
FROM SPANNER_SYS.ROW_DELETION_POLICIES 
WHERE UNDELETABLE_ROWS > 0;
6 TTL for Cloud Spanner.jpg

使ってみる

有効期間(TTL)を使用すると、Spanner のデータベース内の古く、不要なデータを定期的に自動削除できます。このバックグラウンド クリーンアップにより、ストレージとバックアップの費用を削減し、大量のデータをスキャンする必要のあるクエリのパフォーマンスが向上します。また、データ保持ポリシーの自動化にも役立ちます。

管理者は、タイムスタンプ列と期間(たとえば、最終更新日 + 90 日)を使用して、行削除ポリシーをテーブルに接続します。バックグラウンドでは、Spanner が削除対象となる行がないか定期的に確認し、インターリーブされた子も含めて一括で削除します。管理者が手動で記述する必要があるカスタム アプリケーション コードやスクリプトとは異なり、TTL は自動的に並列化と再試行を処理して、複雑なパーティショニングやエラー処理ロジックなしで進捗を確保し、他のワークロードへの影響を最小限に抑えます。TTL は現在、追加費用なしで、すべての Spanner データベースで利用可能です。詳細は、プロダクト ドキュメントをご覧ください。

- ソフトウェア エンジニアリング マネージャー Radu Dragan

- Cloud Spanner プロダクト マネージャー Justin Makeig