将数据导出到 Spanner(反向 ETL)

如需就此功能提供反馈或请求支持,请发送电子邮件至 bq-cloud-spanner-federation-preview@google.com

本文档介绍如何设置从 BigQuery 到 Spanner 的反向提取、转换和加载(反向 ETL)工作流。为此,您可以使用 EXPORT DATA 语句将数据从 BigQuery 表导出到 Spanner 表。

此反向 ETL 工作流将 BigQuery 中的分析功能与 Spanner 中的低延迟时间和高吞吐量相结合。此工作流可让您向应用用户提供数据,而不会耗尽 BigQuery 的配额和限制。

准备工作

所需的角色

如需获得将 BigQuery 数据导出到 Spanner 所需的权限,请让管理员向您授予项目的以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

您也可以通过自定义角色或其他预定义角色来获取所需的权限。

限制

  • 以下 BigQuery 数据类型在 Spanner 中没有等效数据类型,不受支持:
Spanner 数据库方言 不支持的 BigQuery 类型
所有方言
  • STRUCT
  • GEOGRAPHY
  • DATETIME
  • RANGE
  • TIME
GoogleSQL
  • BIGNUMERIC:支持的 NUMERIC 类型不够宽。请考虑在查询中向 NUMERIC 类型添加显式类型转换。
  • 所导出行的大小上限为 1 MiB。

  • Spanner 会在导出期间强制执行参照完整性。如果目标表是另一个表的子表(INTERLEAVE IN PARENT),或者目标表具有外键约束条件,则系统会在导出期间验证外键和父键。如果导出的行被写入到具有 INTERLEAVE IN PARENT 的 Table,并且父行不存在,导出将失败,并显示“父行缺失。行无法写入”错误。如果导出的行被写入到具有外键约束条件的表中,并且引用不存在的键,则导出将失败并显示“违反外键约束条件”错误。导出到多个表时,我们建议按顺序导出,以确保在导出过程中保持参照完整性。这通常意味着,在导出引用父表和外键引用的表之前,先导出父表和被外键引用的表。

    如果要导出的目标表具有外键约束条件,或者是另一个表的子表(INTERLEAVE IN PARENT),则必须先填充父表,然后才能导出子表,并且父表应包含所有相应的键。如果父表没有一组完整的相关键,则尝试导出子表将会失败。

  • 导出到 Spanner 的作业时长上限为 6 小时。如需了解如何优化大型导出作业,请参阅导出优化。或者,您也可以考虑将输入拆分为单独的数据块,以便作为单独的导出作业进行导出。

  • 只有 BigQuery 企业版或企业 Plus 版支持导出到 Spanner。不支持 BigQuery 标准版和按需计算。

使用 spanner_options 选项配置导出

您可以使用 spanner_options 选项指定目标 Spanner 数据库和表。配置以 JSON 字符串的形式表示,如以下示例所示:

EXPORT DATA OPTIONS(
   uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
  format='CLOUD_SPANNER',
   spanner_options = """{
      "table": "TABLE_NAME",
      "priority": "PRIORITY",
      "tag": "TAG",
   }"""
)

替换以下内容:

  • PROJECT_ID:您的 Google Cloud 项目的名称。
  • INSTANCE_ID:您的数据库实例的名称。
  • DATABASE_ID:您的数据库的名称。
  • TABLE_NAME:现有目标表的名称。
  • PRIORITY(可选):写入请求的优先级。允许使用的值:LOWMEDIUMHIGH。默认值:MEDIUM
  • TAG(可选):请求标记,可帮助识别 Spanner 监控中的导出器流量。默认值:bq_export

导出查询要求

如需将查询结果导出到 Spanner,结果必须满足以下要求:

  • 结果集中的所有列必须存在于目标表中,并且列的类型必须匹配。
  • 结果集必须包含目标表的所有 NOT NULL 列。
  • 列值不得超过 Spanner 表中的数据大小限制
  • 必须先将任何不受支持的列类型转换为某种受支持的类型,然后再导出到 Spanner。

导出数据

您可以使用 EXPORT DATA 语句将数据从 BigQuery 表导出到 Spanner 表。

以下示例从名为 mydataset.table1 的表中导出选定的字段:

EXPORT DATA OPTIONS (
  uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
  format='CLOUD_SPANNER',
  spanner_options="""{ "table": "TABLE_NAME" }"""
)
AS SELECT * FROM mydataset.table1;

替换以下内容:

  • PROJECT_ID:您的 Google Cloud 项目的名称
  • INSTANCE_ID:您的数据库实例的名称
  • DATABASE_ID:您的数据库的名称
  • TABLE_NAME:现有目标表的名称

导出具有相同 rowkey 值的多个结果

当您导出包含具有相同 rowkey 值的多个行的结果时,写入 Spanner 的值最终将位于同一个 Spanner 行中。导出操作生成的 Spanner 行集中将仅包含单个匹配的 BigQuery 行(无法保证是哪一行)。

导出优化

如需优化将记录从 BigQuery 导出到 Spanner 的过程,您可以尝试以下操作:

  • 在 Spanner 目标实例中增加节点数量。请注意,在导出操作的早期阶段,增加实例中的节点数量可能不会立即导致导出吞吐量增加。由于 Spanner 执行基于负载的拆分,因此可能会出现轻微延迟。使用基于负载的分片时,导出吞吐量会逐渐增加,并在短时间内稳定下来。如需详细了解如何最大限度地提高写入吞吐量,请参阅性能概览

  • spanner_options 中指定 HIGH 优先级。 不过,这样做可能会导致同一实例提供的其他工作负载的性能大幅下降。

  • 避免对查询结果进行排序。如果结果集包含所有主键列,则导出器会自动对目标表的主键进行排序,以简化写入并最大限度地减少争用。

    如果目标表的主键包含生成的列,则应将生成的列的表达式添加到查询中,以确保导出的数据正确排序。

价格

如需了解数据导出价格,请参阅 BigQuery 价格

导出数据后,如果您将数据存储在 Spanner 中,则需要为此付费。如需了解详情,请参阅 Spanner 价格