Spanner から Spanner Omni にデータを複製する

このドキュメントでは、Google Cloud のマネージド Spanner と、AWS やオンプレミス データセンターなどの外部環境の Spanner Omni の間で、障害復旧トポロジを設定するためのパターン、構成手順、運用ガイダンスについて説明します。

変更ストリームを使用したトランザクション ストリーミングと、Cross-Cloud Interconnect を介した専用ネットワーク接続を組み合わせることで、クラウドの境界を越えて低い目標復旧時点(RPO)と目標復旧時間(RTO)を達成できます。

アーキテクチャの概要

クロスクラウド障害復旧トポロジでは、Google Cloud の Spanner がプライマリ データベースとして機能し、Spanner Omni がスタンバイ デプロイまたはセカンダリ障害復旧サイトとして機能します。変更ストリームを使用して、トランザクションの変更を継続的に複製できます。

次の表は、AWS 上のプライマリ Spanner デプロイとセカンダリ Spanner Omni デプロイのデータベース機能、ロール、運用境界を比較したものです。

プライマリ Spanner とセカンダリ Spanner Omni のデプロイの比較
機能またはディメンション プライマリ サイト: Google Cloudの Spanner セカンダリ サイト: AWS 上の Spanner Omni
デプロイモデル

Google Cloudのフルマネージド サービス。

AWS 上のセルフマネージド ソフトウェア(Amazon Elastic Compute Cloud(Amazon EC2)や Amazon Elastic Kubernetes Service(Amazon EKS)など)。

可用性 SLA

マルチリージョン構成では最大 99.999%、リージョン構成では最大 99.99%。詳細については、Spanner SLA をご覧ください。

お客様が管理。インフラストラクチャとトポロジによって異なります。

レプリケーション モード

ゾーンとリージョンにまたがる Paxos ベースの同期レプリケーション。

変更ストリームを使用した非同期の準リアルタイム変更データ キャプチャ(CDC)。

目標復旧時点(RPO)

マネージド インスタンス内ではほぼゼロ。

パイプラインのスループットとネットワーク レイテンシに応じて、クラウド境界を越えて 1 秒未満から数秒。

目標復旧時間(RTO)

レプリカ間での即時かつ自動のフェイルオーバー。

DNS とトラフィックのスイッチオーバーのランブックによって異なります。

ネットワーク トランジット レイヤ

Virtual Private Cloud(VPC)ネットワーク ピアリングまたは Cloud Interconnect。

AWS Direct Connect に接続された Cross-Cloud Interconnect。

バックアップ ストレージ ターゲット

Google が管理する Spanner バックアップ。マネージド Spanner にのみ復元できます。

Cloud Storage または Amazon Simple Storage Service(Amazon S3)。Spanner Omni にのみ復元できます。

始める前に

Spanner と Spanner Omni 間のレプリケーションを構成する前に、環境が次の要件を満たしていることを確認してください。

  • 一致する宛先容量をプロビジョニングする: プライマリ Spanner インスタンスの CPU、メモリ、ストレージ I/O 容量に合わせて、宛先の Spanner Omni デプロイのサイズを調整します。デプロイのサイズが小さすぎると、レプリケーション ラグが発生し、フェイルオーバー中にスタンバイ クラスタがワークロードを処理できなくなる可能性があります。詳しくは、システム要件をご覧ください。
  • データベース スキーマとベースライン データを同期する: ソース Spanner データベースと同じ SQL 言語(GoogleSQL または PostgreSQL)とスキーマ定義を使用して、Spanner Omni に移行先のデータベースとテーブルを作成します。マネージド Spanner バックアップを Spanner Omni に復元することはできないため、既存のデータを Spanner から Cloud Storage の Avro ファイルにエクスポートし、Spanner Omni にインポートします。詳細については、スキーマとデータモデル、Spanner Omni を使用して開発する、Spanner から Avro にデータベースをエクスポートする、データのインポートとエクスポートをご覧ください。
  • プライベート ネットワーク接続を確立する: Google Cloud VPC ネットワークと外部環境の間にプライベート ネットワーク ルーティングを構成して、レプリケーション ワーカーが Spanner と Spanner Omni gRPC エンドポイントの両方に接続できるようにします。詳細については、Network Connectivity プロダクトの選択と Cross-Cloud Interconnect でレプリケーションを高速化するをご覧ください。

変更ストリームを使用してデータを継続的にレプリケートする

クロスクラウドのビジネス継続性を必要とするアプリケーションの場合、Spanner の変更ストリームは、トランザクション データの変更(INSERT、UPDATE、DELETE オペレーション)を commit タイムスタンプ順に出力します。継続的なレプリケーション パイプラインは、 Google Cloud の Spanner から変更レコードを読み取り、Spanner Omni デプロイに書き込みます。

変更ストリームをクロスクラウド レプリケーションに使用すると、次のメリットがあります。

  • アクティブ / パッシブ スタンバイ: Spanner Omni でウォーム レプリカを維持し、フェイルオーバーを開始したときにワークロードを処理できるようにします。
  • 選択的レプリケーション: 変更ストリームを構成して、データベース全体を監視したり、特定のテーブルと列に制限したりして、クロスクラウド転送費用を削減できます。
  • 言語の同等性: Spanner Omni は、Spanner と同じ GoogleSQL 言語と PostgreSQL 言語、スキーマ セマンティクスをサポートしているため、カットオーバー後にアプリケーション クエリを変更せずに実行できます。

ステップ 1: ソース データベースに変更ストリームを作成する

ソース Spanner データベースに変更ストリームを作成して、ターゲット テーブルの変更を追跡します。たとえば、Spanner データベースで次の DDL ステートメントを実行します。

CREATE CHANGE STREAM CHANGE_STREAM_NAME
FOR TABLE_NAMES
OPTIONS (
  retention_period = '7d',
  value_capture_type = 'NEW_ROW_AND_OLD_VALUES'
);

次のように置き換えます。

  • CHANGE_STREAM_NAME: 変更ストリームの名前(例: CsToOmniDrStream)。
  • TABLE_NAMES: 追跡するテーブルのカンマ区切りリスト(例: Customers, Orders, AccountBalances)。データベース内のすべてのテーブルを追跡する場合は ALL。

retention_period を '7d' に設定すると、変更ストリーム レコードが最大 7 日間保持されます。これにより、レプリケーション パイプラインでメンテナンスや接続の中断が長時間発生した場合でも、データ損失を防ぐことができます。詳細については、変更ストリームの作成と管理をご覧ください。

ステップ 2: 変更データ キャプチャ パイプラインをデプロイする

Spanner から Spanner Omni に変更をストリーミングするには、Apache Beam で Dataflow を使用して継続的な変更データ キャプチャ(CDC)パイプラインをデプロイするか、Google Kubernetes Engine(GKE)または Amazon EKS でカスタム ワーカー Pod を実行します。

本番環境のレプリケーション パイプラインは、次のタスクを実行します。

  • パーティションの読み取り: Spanner Change Streams API または Apache Beam SpannerIO コネクタを使用して、動的な変更ストリーム パーティション全体で変更レコードを読み取ります。詳細については、変更ストリームのパーティション、レコード、クエリと Dataflow を使用して変更ストリーム レコードを処理するをご覧ください。
  • ミューテーションのバッファリングと順序付け: トランザクションの一貫性を維持し、書き込みスループットを最大化するために、キー範囲またはテーブルごとに commit タイムスタンプ(commit_timestamp)に従ってトランザクションをシーケンス化してバッチ処理します。
  • Spanner Omni への書き込み: gRPC 経由で Spanner Omni デプロイのプライベート エンドポイントに接続し、バッチ処理されたミューテーションを適用します。暗号化で Apache Beam SpannerIO コネクタを使用する場合は、TLS に Apache Beam 2.69.0 以降、相互 TLS(mTLS)に 2.75.0 以降を使用します。詳細については、Apache Beam と SpannerIO を使用して Spanner Omni に接続すると認証と認可をご覧ください。
  • レプリケーション ラグをモニタリングする: 現在時刻と処理された変更レコードの commit_timestamp の差を追跡して、レプリケーションの遅延をアラートで通知できるようにします。

Dataflow または Apache Beam を使用する場合は、Apache Beam Java SDK を使用する必要があります。Python SDK には変更ストリーム コネクタが含まれていないためです。カスタム ワーカー Pod の場合、この Python の例では、TLS 暗号化を使用して Spanner Omni クライアントを構成し、変更ストリームのミューテーションのバッチを宛先データベースに適用する方法を示します。大量のワークロードの場合は、一度に 1 つのレコードを commit するのではなく、並列ワーカー プロセス間で重複しないミューテーションを commit タイムスタンプ順にキューに入れてバッチ処理します。

from google.cloud import spanner
from google.cloud.spanner_v1 import InstanceType

# Configure the Spanner Omni target client
omni_client = spanner.Client(
    client_options={"api_endpoint": "ENDPOINT"},
    instance_type=InstanceType.OMNI,
    ca_certificate="PATH_TO_CA_CERT",
)
# Spanner Omni uses "default" as the instance ID
omni_instance = omni_client.instance("default")
omni_database = omni_instance.database("DATABASE_ID")


def apply_cdc_mutations_to_omni(records):
    """Applies a batch of ordered change stream records to Spanner Omni."""

    def write_batch(transaction):
        for record in records:
            table_name = record["tableName"]
            mutation_type = record["mutationType"]  # INSERT, UPDATE, DELETE
            row_data = record.get("columnValues", {})

            if mutation_type in ("INSERT", "UPDATE"):
                transaction.insert_or_update(
                    table=table_name,
                    columns=list(row_data.keys()),
                    values=[list(row_data.values())],
                )
            elif mutation_type == "DELETE":
                key_columns = record["keyValues"]
                transaction.delete(
                    table=table_name,
                    keyset=spanner.KeySet(keys=[list(key_columns.values())]),
                )

    omni_database.run_in_transaction(write_batch)

次のように置き換えます。

  • ENDPOINT: Spanner Omni インスタンスのプライベート gRPC エンドポイントとポート(例: spanner-omni.internal.example.com:15000)。
  • PATH_TO_CA_CERT: Spanner Omni デプロイの認証局(CA)証明書のファイルパス。
  • DATABASE_ID: 宛先 Spanner Omni データベースの ID。

クライアント接続の構成の詳細については、Python クライアント ライブラリを使用して Spanner Omni に接続するをご覧ください。

Cross-Cloud Interconnect でレプリケーションを高速化する

Google Cloudと別のクラウド プロバイダ間の公共のインターネットまたは IPsec VPN トンネルに依存すると、ネットワーク ジッター、パケットロス、帯域幅制限、可変レプリケーション レイテンシが発生する可能性があります。低い RPO が必要な本番環境ワークロードの場合は、Cross-Cloud Interconnect を使用して、Google Cloud と外部クラウド プロバイダの間に専用の高速物理接続を確立します。

次の表は、公共のインターネットまたは IPsec VPN 接続と Cross-Cloud Interconnect のネットワーク特性を比較したものです。

クロスクラウド レプリケーションのネットワーク転送オプションの比較
ネットワーク指標 公共のインターネットまたは IPsec VPN Cross-Cloud Interconnect
リンク容量

トンネルあたり 1.25 Gbps ~ 3 Gbps。

リンクあたり 10 Gbps または 100 Gbps の専用光帯域幅。

ネットワーク レイテンシとジッター

インターネットのトランジット パスが変動し、予測できない。

確定的で低レイテンシのプライベート ルーティング。

可用性 SLA

エンドツーエンドのパフォーマンス SLA はありません。

冗長接続で構成されている場合、99.9% または 99.99% の可用性 SLA。

データ転送の暗号化

IPsec のオーバーヘッドとソフトウェア暗号化の制限。

Cloud Interconnect(IEEE 802.1AE)のラインレート MACsec 暗号化。詳細については、Cloud Interconnect の MACsec の概要をご覧ください。

データ転送費用

標準のインターネット下り(外向き)料金。

Cloud Interconnect のデータ転送料金の引き下げ。

ネットワーク構成ワークフローの概要

レプリケーション パイプラインに Cross-Cloud Interconnect を設定するには、次の手順を完了します。

  1. Cross-Cloud Interconnect 接続を注文する: リモート クラウド プロバイダのロケーションとペアになるコロケーション施設で、プライマリと冗長 Cross-Cloud Interconnect ポートを注文します。たとえば、gcloud compute interconnects create コマンドを実行します。

    gcloud compute interconnects create CONNECTION_NAME \
      --interconnect-type=DEDICATED \
      --link-type=CAPACITY \
      --requested-link-count=LINK_COUNT \
      --location=GOOGLE_CLOUD_LOCATION \
      --remote-location=REMOTE_LOCATION \
      --noc-contact-email=CONTACT_EMAIL
    

    次のように置き換えます。

    • CONNECTION_NAME: Cross-Cloud Interconnect 接続の名前。
    • CAPACITY: リンク容量(LINK_TYPE_ETHERNET_10G_LR、LINK_TYPE_ETHERNET_100G_LR など)。
    • LINK_COUNT: リクエストするリンクの数。
    • GOOGLE_CLOUD_LOCATION: Google Cloud ロケーションのエッジ アベイラビリティ ドメイン(例: iad-zone1-1)。
    • REMOTE_LOCATION: リモート クラウド プロバイダのロケーション(例: aws-us-east-1)。
    • CONTACT_EMAIL: ネットワーク オペレーションのメールアドレス。

    詳細については、ロケーションを選択すると AWS ポートを注文するをご覧ください。

  2. Cloud Router と BGP ピアリングを構成する: VLAN アタッチメントを作成し、 Google Cloud VPC ネットワークの Cloud Router とリモート クラウド環境の仮想プライベート ゲートウェイまたはダイレクト接続ゲートウェイの間に Border Gateway Protocol(BGP)セッションを構成します。詳細については、Cloud Router の概要、 Google Cloud リソースを構成する、AWS リソースを構成するをご覧ください。

  3. ルート伝播を検証する: 両方のネットワークのルートテーブルが重複しない CIDR ブロックを伝播し、CDC パイプライン ワーカーと Spanner Omni ノードがプライベート IP アドレスを介してのみ通信することを確認します。詳細については、接続を確認するをご覧ください。

詳細な設定手順については、Cross-Cloud Interconnect のドキュメントのアマゾン ウェブ サービスに接続するをご覧ください。

フェイルオーバーとランブックのチェックリスト

Google Cloud の Spanner から Spanner Omni へのスイッチオーバーまたはフェイルオーバーを実行する場合は、次の操作手順に沿って操作します。

  1. 処理中の変更をドレインする: プライマリ Spanner データベース(到達可能な場合)へのアプリケーションの書き込みを停止し、CDC レプリケーション パイプラインが最新の commit タイムスタンプまでのすべての変更ストリーム レコードを処理したことを確認します。
  2. アプリケーション接続をリダイレクトする: アプリケーション構成プロファイル、接続文字列、Kubernetes Secret を更新して、Google Cloudの Spanner ではなく Spanner Omni エンドポイントに接続します。
  3. DNS とトラフィック ルーティングを更新する: DNS レコードまたはグローバル ロードバランサのターゲットを切り替えて、クライアント トラフィックをアプリケーション ティアと Spanner Omni デプロイのフロントエンドとなるロードバランサにルーティングします。
  4. 復旧後に再同期する: プライマリGoogle Cloud 環境を復元した後、フェイルバックする前にレプリケーションの方向を逆にします。Spanner Omni からの変更をキャプチャするには、変更ストリームと Debezium コネクタを使用して変更を Apache Kafka にパブリッシュし、コンシューマーが変更を Spanner に適用します。または、Spanner Omni データベースを Cloud Storage の Avro ファイルにエクスポートして、Spanner にインポートすることもできます。詳細については、データのインポートとエクスポートと Spanner Avro ファイルをインポートするをご覧ください。

次のステップ