変更ストリームは、Cloud Spanner データベースのデータ変更(挿入、更新、削除)をほぼリアルタイムで監視してストリーミングします。
このページでは、Spanner の変更ストリームにより実施される処理の内容、および変更ストリームが機能する仕組みについて説明します。データベースの変更ストリームを作成して管理し、他のサービスに接続する方法については、次のステップの手順に従ってください。
変更ストリームの目的
変更ストリームは、データの変更を他のサービスにストリーミングする、柔軟かつスケーラブルな手段となります。一般的なユースケースには次のものがあります。
Spanner のデータ変更を BigQuery などのデータ ウェアハウスにレプリケートして分析する。
Pub/Sub などのメッセージ キューに送信されたデータ変更に基づいてアプリケーション ロジックをトリガーする。
コンプライアンスやアーカイブ目的で、データ変更を Cloud Storage に保存する。
変更ストリームの構成
Spanner は、テーブルやインデックスと同様に、変更ストリームをスキーマ オブジェクトとして扱います。したがって、DDL ステートメントを使用して変更ストリームを作成、変更、削除し、他の DDL マネージド スキーマ オブジェクトと同様にデータベースの変更ストリームを表示できます。
データベース全体でデータ変更を監視するように変更ストリームを構成するか、スコープを特定のテーブルと列に制限できます。1 つのデータベースには複数の変更ストリームを含めることができ、特定のテーブルやカラムは、制限の範囲内で複数のストリームに監視させることができます。
変更ストリームを構成して、データの保持期間、値キャプチャ タイプ、TTL ベースの削除のフィルタ、またはテーブル変更フィルタを指定することもできます。
変更ストリームを作成する DDL を発行すると、長時間実行オペレーションが開始されます。完了すると、新しい変更ストリームがすぐに割り当てられたテーブルと列の監視を開始します。
暗黙的にテーブルと列を監視する
テーブル全体を監視する変更ストリームは、テーブル定義が更新されても、そのテーブル内のすべての列を暗黙的に監視します。たとえば、そのテーブルに新しい列を追加すると、変更ストリームは自動的に新しい列を監視し始めます。変更ストリームの構成を変更する必要はありません。同様に、変更ストリームは、そのテーブルからドロップされた列を自動的に監視しなくなります。
データベース全体の変更ストリームも同じように機能します。すべてのテーブルのすべての列が暗黙的に監視され、変更ストリームの作成後に追加されたテーブルや列は、自動的に監視され、破棄されたテーブルや列は監視されなくなります。
テーブルと列の明示的な監視
テーブル内の特定の列のみを監視するように変更ストリームを構成し、後でテーブルに列を追加した場合、変更ストリームが監視を行うように再構成しない限り、変更ストリームはそれらの列の監視を開始しません。
データベースのスキーマは、変更ストリームを、明示的に監視する列またはテーブルの依存オブジェクトとして扱います。そのような列またはテーブルを削除するには、まず明示的に監視している変更ストリームの構成から手動で削除する必要があります。
変更ストリームによる監視対象となるデータ変更の種類
変更ストリームが監視するデータ変更には、監視対象のテーブルと列に対するすべての挿入、更新、削除が含まれます。これらの変更の要因には次のものが含まれます。
インターリーブされた子テーブルでのカスケード削除
有効期間ルールによる削除
変更ストリームは、ユーザーが作成した列とテーブルでのみデータの変更を監視できます。インデックス、ビュー、その他の変更ストリーム、システム テーブル(情報スキーマや統計情報テーブルなど)は監視しません。列が主キーの一部でない限り、変更ストリームは生成された列を監視しません。主キー列は常にトラッキングされます。
また、変更ストリームは、スキーマの変更や、スキーマの変更によって直接発生するデータの変更を監視しません。たとえば、データベース全体を監視する変更ストリームでは、テーブルの削除は、操作によってデータベースからテーブルのすべてのデータが削除されることになりますが、データの変更として扱われることはありません。
Spanner が変更ストリームを作成して保存する方法
Spanner は、変更ストリームで監視される列のデータ変更を検出するたびに、データ変更レコードを内部ストレージに書き込みます。これは、同じトランザクション内で、データ変更と同期して行われます。Spanner によってこれらの書き込みが両方とも同じ場所に配置され、同じサーバーで処理されることで書き込み処理が最小限に抑えられます。
データ変更レコードの内容
変更ストリームによって書き込まれるすべてのデータ変更レコードには、データの変更に関する次の情報が含まれます。
影響を受けるテーブルの名前
変更された行を識別する主キーの名前、値、データ型
変更ストリームの定義に基づいてキャプチャされ、変更された行の列の名前とデータ型。
行の列の古い値。古い値と、追跡するコンテンツ(変更された列のみ、または追跡された行全体)を使用できるかどうかは、ユーザーが構成した値キャプチャ タイプによって異なります。
行の列の新しい値。新しい値を使用できるかどうかと、追跡するコンテンツは、ユーザーが構成した値キャプチャ タイプによって異なります。
変更タイプ(挿入、更新、削除)
commit タイムスタンプ
トランザクション ID
レコード シーケンス番号
データ変更レコードの値のキャプチャ タイプ
データ変更レコードの構造の詳細については、データ変更レコードをご覧ください。
データの保持
変更ストリームでは、データ変更レコードが 1~7 日間保持されます。DDL を使用して、データ ストリームの保持期間の上限を指定できます。この上限には、変更ストリームを最初に作成したときにデフォルトで設定される 1 日以外の値を指定できます。または、後で随時調整することもできます。変更ストリームのデータの保持期間の上限を引き下げると、すべての履歴変更データが新しい上限よりも早く変更され、その変更ストリームの閲覧者は完全に利用できなくなります。
このデータ保持期間にはトレードオフがあります。保持期間が長いほど、ストリームのデータベースに対するストレージの需要が増加します。
値キャプチャ タイプ
変更ストリームの値キャプチャ タイプの構成オプションは、変更された行の値を記録する方法を制御します。DDL を使用して、変更ストリームに次のいずれかの値キャプチャ タイプを指定できます。
OLD_AND_NEW_VALUES
: 行の変更された列の古い値と新しい値の両方をキャプチャします。NEW_VALUES
: キー以外の列の新しい値のみを取得し、古い値は取得しません。NEW_ROW
: 列のいずれかが変更されるたびに、監視された列のすべての新しい値(変更済みと変更なしの両方)をキャプチャします。古い値はキャプチャされません。NEW_ROW_AND_OLD_VALUES
: 変更された列と変更されていない列の両方の新しい値と、変更された列の古い値をキャプチャします。
有効期間に基づく削除を除外する
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
に設定します。フィルタは、同時に複数設定できます。
変更ストリームの作成時にテーブル変更タイプのフィルタを追加するか、既存の変更ストリームのテーブル変更タイプのフィルタを変更します。
変更ストリームの読み取り
Spanner では、変更ストリームのデータを読み取るために、次のような方法があります。
Dataflow から、Apache Beam SpannerIO コネクタを使用して読み取る。これは、ほとんどの変更ストリーム アプリケーションで推奨されるソリューションです。Google は、一般的なユースケース用の 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 のコネクタと同じ方法でデータ変更レコードを読み取ることができ、変更ストリーム データの読み取り時に可能な限り低いレイテンシと引き換えに抽象化を回避できます。
詳細については、変更ストリームをクエリするをご覧ください。変更ストリームのクエリと返されたレコードの解釈の詳細については、ストリームのパーティション、レコード、クエリをご覧ください。
Kafka コネクタの使用
Kafka コネクタは、変更ストリーム レコードを Kafka トピックに直接出力します。 Spanner API を使用して変更ストリームのクエリの詳細を抽象化します。
変更ストリームと Kafka コネクタが連携する仕組みについては、Kafka コネクタを使用して変更ストリーム接続を構築するをご覧ください。
制限事項
データベースが持つことができる変更ストリームの最大数や、1 つの列を監視できるストリームの最大数など、変更ストリームにはいくつかの上限があります。全一覧については、変更ストリームの制限をご覧ください。
権限
変更ストリームでは、以下が使用されます。
変更ストリームを作成、更新、削除するには、
spanner.databases.updateDdl
が必要です。変更ストリームのデータを読み取るには、
spanner.databases.select
が必要です。
SpannerIO コネクタを使用する場合、変更ストリーム データを読み取る Dataflow ジョブのオーナーは、アプリケーション データベースまたは別のメタデータ データベースに対する追加の IAM 権限を付与されている必要があります。メタデータ データベースを作成するをご覧ください。
次のステップ
変更ストリームを作成、管理するための DDL 構文について確認する。
変更ストリームとテンプレートを使用して、Spanner から BigQuery または Cloud Storage に変更を複製します。
変更ストリーム アーキテクチャの詳細、API を使用して変更ストリームをクエリする方法、返されたレコードを解釈する方法など、変更ストリームの詳細もご覧ください。
Kafka コネクタを使用して変更ストリーム データを処理する方法を確認する。