変更ストリームの概要

変更ストリームにより、Spanner データベースのデータ変更(挿入、更新、削除)はほぼリアルタイムで監視、ストリーミングされます。

このページでは、Spanner の変更ストリームにより実施される処理の内容、および変更ストリームが機能する仕組みについて説明します。データベースで変更ストリームを作成して管理し、他のサービスに接続する方法については、次のステップのリンクをご覧ください。

変更ストリームの目的

変更ストリームは、データの変更を他のサービスにストリーミングする、柔軟かつスケーラブルな手段となります。一般的なユースケースには次のものがあります。

  • Spanner のデータ変更を BigQuery などのデータ ウェアハウスにレプリケートして分析する。

  • Pub/Sub などのメッセージ キューに送信されたデータ変更に基づき、アプリケーション ロジックをトリガーする。

  • コンプライアンスやアーカイブの目的で、データ変更を Cloud Storage に保存する。

変更ストリームの構成

Spanner は、テーブルやインデックスと同様に、変更ストリームをスキーマ オブジェクトとして扱います。したがって、他の DDL マネージド スキーマ オブジェクトと同様に、DDL ステートメントを使用して変更ストリームを作成、変更、削除し、データベースの変更ストリームを確認できます。

変更ストリームを構成して、データベース全体のデータ変更を監視したり、そのスコープを特定のテーブルと列に制限したりできます。1 つのデータベースには複数の変更ストリームを含めることができ、特定のテーブルやカラムは制限の範囲内で複数のストリームに監視させることができます。

必要に応じて、次のコマンドを使用して変更ストリームを構成できます。

変更ストリームを作成する DDL を発行すると、長時間実行オペレーションが開始されます。オペレーションが完了すると、新しい変更ストリームは割り当てられたテーブルと列のモニタリングをすぐに開始します。

テーブルと列を暗黙的に監視する

テーブル全体を監視する変更ストリームは、テーブル定義が更新された場合でも、そのテーブル内のすべての列を暗黙的に監視します。たとえば、テーブルに新しい列を追加すると、変更ストリームの構成を変更しなくても、変更ストリームは自動的に新しい列の監視を開始します。同様に、変更ストリームは、そのテーブルから削除された列の監視を自動的に停止します。

データベース全体の変更ストリームも同様に機能します。すべてのテーブルのすべての列を暗黙的に監視し、変更ストリームの作成後に追加されたテーブルまたは列を自動的に監視し、削除されたテーブルまたは列の監視を停止します。

テーブルと列を明示的に監視する

テーブル内の特定の列のみを監視するように変更ストリームを構成し、後でテーブルに列を追加した場合、変更ストリームが監視を行うように再構成しない限り、変更ストリームはそれらの列の監視を開始しません。

データベースのスキーマでは、変更ストリームは、明示的に監視する列またはテーブルの依存オブジェクトとして扱われます。こういった列またはテーブルを削除するには、まず明示的に監視している変更ストリームの構成から手動で削除する必要があります。

変更ストリームによる監視対象となるデータ変更の種類

変更ストリームが監視するデータ変更には、監視対象のテーブルと列に対して行われたすべての挿入、更新、削除が含まれます。これらの変更の要因として次のものがあげられます。

変更ストリームは、ユーザーが作成した列とテーブルのデータ変更のみ監視できます。インデックス、ビュー、他の変更ストリーム、情報スキーマや統計テーブルなどのシステム テーブルは監視されません。列が主キーの一部でない限り、変更ストリームは生成された列を監視しません。主キー列は常に追跡されます。

さらに、変更ストリームは、デフォルト値のバックフィルを除き、スキーマの変更やスキーマの変更に直接起因するデータの変更は監視しません。たとえば、データベース全体を監視する変更ストリームでは、テーブルの削除は、操作によってデータベースからテーブルのすべてのデータが削除されることになりますが、データの変更として扱われることはありません。

Spanner の変更ストリームの書き込みと格納の仕組み

Spanner は、変更ストリームで監視される列のデータ変更を検出するたびに、データ変更レコードを内部ストレージに書き込みます。データ変更の書き込みとデータ変更レコードは、同じトランザクション内で書き込まれます。Spanner によってこれらの書き込みが両方とも同じ場所に配置され、同じサーバーで処理されることで書き込み処理が最小限に抑えられます。その後、トランザクションはデータベースのレプリカに複製され、ストレージとレプリケーションの費用が発生します。詳細については、Spanner の料金をご覧ください。

データ変更レコードの内容

変更ストリームによって書き込まれるすべてのデータ変更レコードには、データ変更に関する次の情報が含まれます。

  • 影響を受けるテーブルの名前

  • 変更された行を識別する主キーの名前、値、データ型

  • 変更ストリームの定義に基づいてキャプチャされ、変更された行の列の名前とデータ型。

  • 行の列の古い値。古い値と、追跡するコンテンツ(変更された列のみ、または追跡された行全体)を使用できるかどうかは、ユーザーが構成した値キャプチャ タイプによって異なります。

  • 行の列の新しい値。新しい値と、追跡するコンテンツを使用できるかどうかは、ユーザーが構成した値キャプチャ タイプによって異なります。

  • 変更タイプ(挿入、更新、削除)

  • commit タイムスタンプ

  • トランザクション ID

  • レコードのシーケンス番号

  • データ変更レコードの値のキャプチャ タイプ

データ変更レコードの構造の詳細については、データ変更レコードをご覧ください。

データの保持

変更ストリームでは、データ変更レコードが 1~30 日間保持されます。データ ストリームの保持期間の上限は、DDL を使用して指定できます。この上限には、変更ストリームを最初に作成したときにデフォルトで設定される 1 日以外の値を指定できます。または、後で随時調整することもできます。変更ストリームのデータの保持期間の上限を引き下げると、すべての履歴変更データが新しい上限よりも早く変更され、その変更ストリームの閲覧者は完全に利用できなくなります。

データの保持期間にはトレードオフがあります。保持期間が長くなると、ストリームのデータベースに対するストレージの需要が高くなります。

値キャプチャ タイプ

変更ストリームの値キャプチャ タイプの構成オプションで、変更された行の値を記録する方法を決定できます。DDL を使用して、変更ストリームに次のいずれかの値キャプチャ タイプを指定できます。

  • OLD_AND_NEW_VALUES: 行の変更された列の古い値と新しい値の両方をキャプチャします。

  • NEW_VALUES: 非キー列の新しい値のみをキャプチャし、古い値はキャプチャしません。

  • NEW_ROW: 監視対象の列の新しい値(変更された列と変更されていない列の両方)を、いずれかの列が変更されるたびにキャプチャします。古い値はキャプチャされない

  • NEW_ROW_AND_OLD_VALUES: 変更された列と変更されていない列の両方の新しい値と、変更された列の古い値をキャプチャします。

有効期間(TTL)に基づく削除を除外する

Spanner では、有効期間(TTL)を使用して、Spanner テーブルからデータを定期的に削除するポリシーを設定できます。デフォルトでは、変更ストリームではすべての TTL ベースの削除が行われます。exclude_ttl_deletes を使用すると、TTL ベースの削除を除外するように変更ストリームを設定できます。TTL ベースの削除を除外するようこのフィルタを設定すると、将来の TTL ベースの削除のみが変更ストリームから除外されます。

このフィルタのデフォルト値は false です。TTL ベースの削除を除外するには、フィルタを true に設定します。変更ストリームの作成時にフィルタを追加するか、フィルタを含めるように既存の変更ストリームを変更することができます。

テーブルの変更タイプ

デフォルトでは、変更ストリームには、挿入、更新、削除など、すべてのテーブル変更が含まれます。使用可能な次のフィルタ オプションを使用して、変更ストリームのスコープでこれらのテーブル変更の 1 つ以上をフィルタします。

  • exclude_insert: INSERT テーブルのすべての変更を除外します。
  • exclude_update: UPDATE テーブルのすべての変更を除外します。
  • exclude_delete: DELETE テーブルのすべての変更を除外します。

これらのフィルタのデフォルト値は false です。特定のタイプのテーブル変更を除外するには、フィルタを true に設定します。フィルタは、同時に複数設定できます。

変更ストリームの作成時にテーブル変更タイプのフィルタを追加するか、既存の変更ストリームのテーブル変更タイプのフィルタを変更します。

トランザクション単位のレコードの除外

デフォルトでは、allow_txn_exclusion DDL オプションが false に設定されているため、変更ストリームはデータベース内のすべての書き込みトランザクションを監視します。allow_txn_exclusion オプションを true に設定すると、変更ストリームで指定された書き込みトランザクションのレコードを無視できます。このオプションを true に設定しない場合、書き込みトランザクションで exclude_txn_from_change_streams パラメータを使用していても、すべての書き込みトランザクションが監視されます。

変更ストリームの作成時にこのオプションを有効にするか、既存の変更ストリームを変更することができます。

書き込みトランザクションを変更ストリームから除外する

書き込みトランザクションを変更ストリームから除外するには、exclude_txn_from_change_streams パラメータを true に設定する必要があります。このパラメータは、TransactionOptions メソッドと BatchWriteRequest メソッドの一部です。このパラメータのデフォルト値は false です。このパラメータは、RPC API、REST API、またはクライアント ライブラリを使用して設定できます。詳細については、変更ストリームから除外する書き込みトランザクションを指定するをご覧ください。

読み取り専用トランザクションでは、このパラメータを true に設定できません。こうすると、API から無効な引数のエラーが返されます。

トランザクションによって変更された列をモニタリングする変更ストリームの場合、exclude_txn_from_change_streamstrue に設定されていると、次の 2 つのシナリオが考えられます。

  • DDL オプション allow_txn_exclusiontrue に設定されている場合、このトランザクション内で行われた更新は変更ストリームに記録されません。
  • DDL オプション allow_txn_exclusion を設定していない場合、または false に設定されている場合、このトランザクション内で行われた更新は変更ストリームに記録されます。

exclude_txn_from_change_streams オプションを設定していない場合、または false に設定されている場合、トランザクションによって変更された列をモニタリングする変更ストリームは、そのトランザクション内で行われた更新をキャプチャします。

変更ストリームの読み取り

Spanner では、変更ストリームのデータを読み取る方法がいくつか用意されています。

  • Dataflow から、Apache Beam SpannerIO コネクタを使用して読み取る。これは、ほとんどの変更ストリーム アプリケーションに推奨されるソリューションです。また、一般的なユースケース用に Dataflow テンプレートも用意されています。

  • Spanner API を使用して直接読み取る。これにより、Dataflow パイプラインの抽象化と機能が犠牲になりますが、速度と柔軟性が最大化されます。

  • Spanner 変更ストリームに Debezium ベースの Kafka コネクタを使用する。このコネクタは、変更レコードを Kafka トピックに直接ストリーミングします。

有向読み取りを使用すると、変更ストリームの読み取りを部分的に分離できます。有向読み取りは、データベース内のトランザクション ワークロードへの影響を最小限に抑えるのに役立ちます。Spanner API を使用して、マルチリージョン インスタンス構成またはカスタム リージョン構成(オプションの読み取り専用リージョンを含む)内の特定のレプリカタイプまたはリージョンに変更ストリームの読み取りをルーティングできます。詳細については、有向読み取りをご覧ください。

Dataflow の使用

Apache Beam SpannerIO コネクタを使用して、変更ストリームからの読み取りを行う Dataflow パイプラインを構築できます。特定の変更ストリームに関する詳細でコネクタを構成した後、新しいデータ変更レコードが自動的に制限のない単一の PCollection データセットに出力され、Dataflow パイプラインで後続の変換によってさらに処理が行われます。

Dataflow はウィンドウ関数を使用して、制限なしコレクションを論理的な要素、つまりウィンドウに分割します。その結果、Dataflow は変更ストリームからの読み取り時に、準リアルタイムのストリーミングを提供します。

Google は、ストリームのすべてのデータ変更を BigQuery データセットに送信する、または Cloud Storage バケットにコピーするなど、一般的な変更ストリームのユースケース向けの Dataflow パイプラインを迅速に構築するためのテンプレートも提供しています。

変更ストリームと Dataflow の連携の詳細については、Dataflow を使用して変更ストリーム接続を構築するをご覧ください。

API の使用

Dataflow を使用して変更ストリーム パイプラインを構築する代わりに、Spanner API を使用して変更ストリームのレコードを直接読み取るコードを記述することもできます。これにより、SpannerIO のコネクタと同じ方法でデータ変更レコードを読み取ることができ、Dataflow の柔軟性を提供せずに、変更ストリーム データの読み取り時に可能な限り低いレイテンシを提供できます。

詳細については、変更ストリームをクエリするをご覧ください。変更ストリームのクエリと返されたレコードの解釈の詳細については、ストリームのパーティション、レコード、クエリをご覧ください。

Kafka コネクタの使用

Kafka コネクタは、変更ストリーム レコードを Kafka トピックに直接出力します。Spanner API を使用して、変更ストリームをクエリする詳細を抽象化します。

変更ストリームと Kafka コネクタの連携の詳細については、Kafka コネクタを使用して変更ストリーム接続を構築するをご覧ください。

上限

変更ストリームには、データベースに設定できる変更ストリームの最大数や、1 つの列を監視できるストリームの最大数など、いくつかの制限があります。全一覧については、変更ストリームの制限をご覧ください。

権限

変更ストリームは次の権限を使用します。

  • 変更ストリームの作成、更新、削除には spanner.databases.updateDdl が必要です。

  • 変更ストリームのデータを読み取るには spanner.databases.select が必要です。

SpannerIO コネクタを使用する場合、変更ストリーム データを読み取る Dataflow ジョブのオーナーには、アプリケーション データベースまたは別のメタデータ データベースに対する追加の IAM 権限を付与されている必要があります。メタデータ データベースを作成するをご覧ください。

次のステップ