将数据从 Spanner 复制到 Spanner Omni

本文档介绍了在Google Cloud 上的代管式 Spanner 与外部环境(例如 AWS 或本地数据中心)中的 Spanner Omni 之间设置灾难恢复拓扑的模式、配置步骤和操作指南。

通过结合使用变更数据流的事务流式传输和跨云互连的专用网络连接,您可以跨云边界实现较低的恢复点目标 (RPO) 和恢复时间目标 (RTO)。

架构概览

在跨云灾难恢复拓扑中,Google Cloud 上的 Spanner 用作主数据库,Spanner Omni 用作备用部署或辅助灾难恢复网站。您可以使用变更数据流持续复制事务性更改。

下表比较了 AWS 上的主 Spanner 部署和辅助 Spanner Omni 部署之间的数据库功能、角色和操作边界。

主 Spanner 和辅助 Spanner Omni 部署的比较
功能或维度 主站点:Spanner 运行在 Google Cloud 次要站点: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)

在托管式实例中接近于零。

跨云边界时为亚秒级到秒级,具体取决于流水线吞吐量和网络延迟时间。

恢复时间目标 (RTO)

跨副本即时自动故障切换。

取决于您的 DNS 和流量切换运行手册。

网络公交图层

虚拟私有云 (VPC) 网络对等互连或 Cloud Interconnect。

跨云互连连接到 AWS Direct Connect。

备份存储目标

Google 管理的 Spanner 备份,只能恢复到托管式 Spanner。

Cloud Storage 或 Amazon Simple Storage Service (Amazon S3),只能恢复到 Spanner Omni。

准备工作

在配置 Spanner 与 Spanner Omni 之间的复制之前,请确保您的环境满足以下要求:

  • 预配匹配的目标容量:调整目标 Spanner Omni 部署的大小,使其与主 Spanner 实例的 CPU、内存和存储 I/O 容量相匹配。部署规模过小可能会导致复制延迟,并阻止备用集群在故障切换期间处理工作负载。如需了解详情,请参阅系统要求。
  • 同步数据库架构和基准数据:在 Spanner Omni 中创建目标数据库和表,并使用与源 Spanner 数据库相同的 SQL 方言(GoogleSQL 或 PostgreSQL)和架构定义。由于您无法将托管式 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 操作)。持续复制流水线会从 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,请使用 Dataflow 和 Apache Beam 部署持续变更数据捕获 (CDC) 流水线,或在 Google Kubernetes Engine (GKE) 或 Amazon EKS 上运行自定义工作器 Pod。

生产复制流水线会执行以下任务:

  • 读取分区:使用 Spanner 变更数据流 API 或 Apache Beam SpannerIO 连接器读取动态变更数据流分区中的变更记录。如需了解详情,请参阅变更数据流分区、记录和查询以及使用 Dataflow 处理变更数据流记录。
  • 缓冲和排序变更:根据每个键范围或表的提交时间戳 (commit_timestamp) 对事务进行排序和批处理,以保持事务一致性并最大限度地提高写入吞吐量。
  • 写入 Spanner Omni:通过 gRPC 连接到 Spanner Omni 部署的专用端点,并应用批量变更。如果您将 Apache Beam SpannerIO 连接器与加密搭配使用,请使用 Apache Beam 2.69.0 或更高版本(对于 TLS)或 2.75.0 或更高版本(对于双向 TLS [mTLS])。如需了解详情,请参阅使用 Apache Beam 和 SpannerIO 连接到 Spanner Omni 以及身份验证和授权。
  • 监控复制延迟:跟踪当前时间与已处理更改记录的 commit_timestamp 之间的差异,以便您在复制延迟时发出提醒。

如果您使用 Dataflow 或 Apache Beam,则必须使用 Apache Beam Java SDK,因为 Python SDK 不包含变更数据流连接器。对于自定义工作器 Pod,此 Python 示例展示了如何使用 TLS 加密配置 Spanner Omni 客户端,并将一批变更数据流变更应用于目标数据库。对于高容量工作负载,请在并行工作器进程中按提交时间戳顺序对不重叠的变更进行排队和批处理,而不是一次提交一条记录:

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。

利用跨云互连加快复制速度

依赖于 Google Cloud与另一个云服务商之间的公共互联网或 IPsec VPN 隧道可能会导致网络抖动、丟包、带宽限制和可变复制延迟。对于需要低 RPO 的生产工作负载,请使用 Cross-Cloud Interconnect 在Google Cloud 与外部云服务提供商之间建立专用的高速物理连接。

下表比较了公共互联网或 IPsec VPN 连接与跨云互连之间的网络特性。

跨云复制的网络传输选项比较
网络指标 公共互联网或 IPsec VPN Cross-Cloud Interconnect
链路容量

每个隧道 1.25 Gbps 至 3 Gbps。

每个链路 10 Gbps 或 100 Gbps 的专用光纤带宽。

网络延迟时间和抖动

互联网传输路径多变且不可预测。

确定性、低延迟的专用路由。

SLA 承诺的可用性

没有端到端性能服务等级协议 (SLA)。

配置冗余连接后,服务等级协议 (SLA) 承诺的可用性可达 99.9% 或 99.99%。

数据传输加密

IPsec 开销和软件加密限制。

MACsec for Cloud Interconnect (IEEE 802.1AE) 线速加密。如需了解详情,请参阅 Cloud Interconnect 的 MACsec 概览。

数据传输费用

标准互联网出站流量费率。

降低了 Cloud Interconnect 数据传输费率。

高级网络配置工作流

如需为复制流水线设置跨云互连,请完成以下简要步骤:

  1. 订购跨云互连:在与远程云服务提供商位置配对的对接网点中订购主要和冗余跨云互连端口。例如,运行 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:跨云互连连接的名称。
    • 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 路由器与远程云环境中的虚拟专用网关或直接连接网关之间配置边界网关协议 (BGP) 会话。如需了解详情,请参阅 Cloud Router 概览、配置 Google Cloud 资源和配置 AWS 资源。

  3. 验证路由传播:验证两个网络中的路由表是否传播不重叠的 CIDR 块,以便 CDC 流水线工作器和 Spanner Omni 节点仅通过专用 IP 地址进行通信。如需了解详情,请参阅验证连接。

如需查看完整的设置说明,请参阅跨云互连文档中的连接到 Amazon Web Services。

故障切换和 Runbook 核对清单

从 Spanner onGoogle Cloud 切换或故障切换到 Spanner Omni 时,请按照以下操作步骤操作:

  1. 排空正在进行的更改:停止应用向主 Spanner 数据库(如果可访问)写入数据,并验证 CDC 复制流水线是否已处理所有变更数据流记录,直至最新提交时间戳。
  2. 重定向应用连接:更新应用配置文件、连接字符串或 Kubernetes 密钥,以连接到 Spanner Omni 端点,而不是Google Cloud上的 Spanner。
  3. 更新 DNS 和流量路由:切换 DNS 记录或全球负载均衡器目标,将客户端流量路由到应用层和 Spanner Omni 部署前端的负载均衡器。
  4. 恢复后重新同步:恢复主要Google Cloud 环境后,请在故障恢复之前反转复制方向。您可以使用变更数据流和 Debezium 连接器从 Spanner Omni 捕获变更,将变更发布到 Apache Kafka,并使用一个使用方将这些变更应用到 Spanner。或者,您也可以将 Spanner Omni 数据库导出到 Cloud Storage 中的 Avro 文件,然后将其导入 Spanner。如需了解详情,请参阅导入和导出数据以及导入 Spanner Avro 文件。

后续步骤