将数据库从 Spanner 导出到 Avro

本页面介绍如何使用 Google Cloud 控制台导出 Spanner 数据库。如需使用 REST API 或 gcloud spanner 命令行工具导出 Spanner 数据库,请完成本页面准备工作部分中的步骤,然后查看 Dataflow 文档的 Spanner 到 Cloud Storage Avro 中的详细说明。导出过程使用 Dataflow,并将数据写入 Cloud Storage 存储桶中的文件夹。生成的文件夹包含一组 Avro 文件和 JSON 清单文件。

准备工作

如需导出 Spanner 数据库,您需要先启用 Spanner、Cloud Storage、Compute Engine 和 Dataflow API:

启用 API

此外,您还需要足够的配额和必要的 IAM 权限。

配额要求

导出作业的配额要求如下:

  • Spanner:导出数据库不需要额外的计算容量,但您可能需要增加更多的计算容量,才能在合理的时间内完成作业。如需了解详情,请参阅优化作业
  • Cloud Storage:要导出数据库,您必须为导出的文件创建存储桶(如果还没有的话)。您可以在 Google Cloud 控制台中执行此操作,无论是通过 Cloud Storage 页面还是在通过 Spanner 页面创建导出任务时。您无需为存储桶设置大小。
  • Dataflow:导出作业与其他 Dataflow 作业具有相同的 CPU、磁盘用量和 IP 地址 Compute Engine 配额
  • Compute Engine:在运行导出作业之前,必须为 Compute Engine 设置初始配额,以供 Dataflow 使用。这些配额表示允许 Dataflow 针对作业使用的资源用量上限。建议使用以下初始值:

    • CPU 数:200
    • 使用中的 IP 地址数:200
    • 标准永久性磁盘:50 TB

    通常情况下,您不必进行其他调整。Dataflow 提供自动扩缩功能,因此您只需为导出期间实际使用的资源付费。如果您的作业可能会使用更多资源,Dataflow 界面会显示警告图标。出现警告图标不会影响作业的完成。

IAM 要求

要导出数据库,您还需要有具备足够权限的 IAM 角色,以便使用导出作业涉及的所有服务。如需了解如何授予角色和权限,请参阅应用 IAM 角色

要导出数据库,您需要以下角色:

如需在导出期间使用 Spanner Data Boost 的独立计算资源,您还需要 spanner.databases.useDataBoost IAM 权限。如需了解详情,请参阅 Data Boost 概览

导出数据库

满足上述配额和 IAM 要求后,您可以导出现有的 Spanner 数据库。

如需将 Spanner 数据库导出到 Cloud Storage 存储桶,请按以下步骤操作。

  1. 转到 Spanner 实例页面。

    转到实例页面

  2. 点击包含数据库的实例的名称。

  3. 点击左侧窗格中的导入/导出菜单项,然后点击导出按钮。

  4. 选择导出文件的存储位置下,点击浏览

  5. 如果您还没有用于导出的 Cloud Storage 存储桶,请执行以下操作:

    1. 点击新建存储桶 新的存储桶界面元素的屏幕截图
    2. 为存储桶输入名称。存储分区名称在 Cloud Storage 中必须是唯一的
    3. 选择默认存储类别和位置,然后点击创建
    4. 点击并选中存储桶。

    如果您已有存储桶,请从初始列表中选择存储桶,或点击搜索 搜索界面元素的屏幕截图 来过滤列表,然后点击并选中存储桶。

  6. 点击选择

  7. 选择要导出的数据库下拉菜单中选择要您导出的数据库。

  8. 可选:如需导出某个较早时间点的数据库,请勾选此复选框并输入时间戳。

  9. 为导出作业选择一个区域下拉菜单中选择一个区域。

  10. 可选:如需使用客户管理的加密密钥对 Dataflow 流水线状态进行加密,请执行以下操作:

    1. 点击显示加密选项
    2. 选择使用客户管理的加密密钥 (CMEK)
    3. 从下拉列表中选择您的密钥。

    此选项不会影响目的地 Cloud Storage 存储桶层级加密。如需为您的 Cloud Storage 存储桶启用 CMEK,请参阅将 CMEK 与 Cloud Storage 搭配使用

  11. 可选:如需使用 Spanner Data Boost 导出,请选中使用 Spanner Data Boost 复选框。如需了解详情,请参阅 Data Boost 概览

  12. 选中确认费用下的复选框,确认您已知晓除了现有 Spanner 实例产生的费用外,还存在其他费用。

  13. 点击导出

    Google Cloud 控制台会显示 Database Import/Export 页面,该页面现在会在导入/导出作业列表中显示导出作业的专列项,包括作业所用时间:

    运行中作业的屏幕截图

作业完成或终止后,会在导入/导出列表中更新状态。如果作业成功,状态会显示为成功

导出作业成功消息

如果作业失败,则会显示失败状态:

导出作业失败消息

如需查看作业的 Dataflow 操作详细信息,请在 Dataflow 作业名称列中点击作业名称。

如果作业运行失败,请检查作业的 Dataflow 日志以获取关于错误的详细信息。

为避免失败的导出作业所创建的文件产生 Cloud Storage 费用,请删除该文件夹及其文件。如需了解如何找到该文件夹,请参阅查看导出内容

关于导出生成的列和变更数据流的说明

存储的已生成列中的值不会导出。列定义会导出到 Avro 架构的 Null 类型记录字段,作为该字段的自定义属性。在新添加的生成列的回填操作完成之前,生成的列会被忽略,就像在架构中不存在一样。

以 Avro 文件形式导出的变更流仅包含变更数据流的架构,不包含任何数据变更记录。

关于导出序列的说明

序列(GoogleSQLPostgreSQL)是用于生成唯一整数值的架构对象。Spanner 会将每个架构对象作为记录字段导出到 Avro 架构,并将其序列种类、跳过的范围和计数器作为该字段的属性。请注意,为了防止序列在导入后被重置并生成重复值,在架构导出期间,GET_INTERNAL_SEQUENCE_STATE()GoogleSQLPostgreSQL)函数会捕获序列计数器。Spanner 向计数器添加 1, 000 的缓冲区,并将新的计数器值写入记录字段。此方法可避免导入后可能发生的重复值错误。如果在数据导出期间对源数据库有更多写入,则应使用 ALTER SEQUENCEGoogleSQLPostgreSQL)语句调整实际序列计数器。

导入时,序列从这个新的计数器(而不是在架构中找到的计数器)开始执行。或者,您也可以使用 ALTER SEQUENCEGoogleSQLPostgreSQL)语句,通过新的计数器更新序列。

在 Cloud Storage 中查看您的导出内容

如需在 Google Cloud 控制台中查看包含导出的数据库的文件夹,请转到 Cloud Storage 浏览器并选择之前选择的存储桶:

转到 Cloud Storage 浏览器

该存储分区内现在存在一个包含导出的数据库的文件夹。此文件夹名称以实例的 ID、数据库名称和导出作业的时间戳开头。该文件夹包含以下内容:

  • 一个 spanner-export.json 文件
  • 您导出的数据库中每个表的 TableName-manifest.json 文件。
  • 一个或多个 TableName.avro-#####-of-##### 文件。扩展名 .avro-#####-of-##### 中的第一组数字表示 Avro 文件的索引(从零开始),第二组数字则表示为每个表生成的 Avro 文件的数量。

    例如,Songs.avro-00001-of-00002 表示包含 Songs 表数据的两个文件中的第二个文件。

  • 您导出的数据库中每个变更数据流ChangeStreamName-manifest.json 文件。

  • 每个变更流都有一个 ChangeStreamName.avro-00000-of-00001 文件。此文件包含空数据,其中仅包含变更数据流的 Avro 架构。

为导入作业选择一个区域

您可能需要根据 Cloud Storage 存储桶的位置选择其他区域。为避免产生出站数据传输费用,请选择与您的 Cloud Storage 存储桶位置匹配的区域。

  • 如果您的 Cloud Storage 存储桶位置是一个区域,您可以通过为导入作业选择同一区域来利用免费网络用量(假设该区域可用)。

  • 如果您的 Cloud Storage 存储桶位置为双区域,您可以利用免费网络用量,从构成导入作业双区域的两个区域中选择一个来使用(假设其中一个区域可用)。

  • 如果导入作业不支持同一位置,或者您的 Cloud Storage 存储桶位置是多区域,则会产生出站流量费用。请参阅 Cloud Storage 数据传输价格,选择产生的数据传输费用最低的区域。

导出表的子集

如果只想导出某些表中的数据,而不是整个数据库中的数据,则可以在导出期间指定这些表。在这种情况下,Spanner 会导出数据库的整个架构,包括您指定的表的数据,并且在导出的文件中保留所有其他表但不为空。

您可以使用 Google Cloud 控制台中的 Dataflow 页面或命令行,指定要导出的表的子集。(Spanner 页面不提供此操作。)

如果您要导出另一个表的子表的数据,则也应该导出其父表的数据。parent如果未导出父级,则导出作业将失败。

如需导出表的子集,请使用 Dataflow 的 Spanner to Cloud Storage Avro 模板开始导出,并使用 Google Cloud 控制台中的 Dataflow 页面或 Google Cloud CLI 指定表,如下所述:

Google Cloud 控制台

如果您使用的是 Google Cloud 控制台中的 Dataflow 页面,则 Cloud Spanner 表名称参数位于基于模板创建作业页面的可选参数部分。可以采用逗号分隔格式指定多个表。

gcloud CLI

如果您使用的是 Google Cloud CLI,请使用 tableNames 参数指定表。例如:

gcloud dataflow jobs run my-export-job \
--gcs-location='gs://dataflow-templates/latest/Cloud_Spanner_to_GCS_Avro' \
--region=us-central1 \
--parameters='instanceId=test-instance,databaseId=example-db,tableNames=table1,outputDir=gs://my-gcs-bucket' \
--max-workers=10

gcloud 中指定多个表需要字典类型参数转义。以下示例使用“|”作为转义字符:

 gcloud dataflow jobs run my-export-job \
--gcs-location='gs://dataflow-templates/latest/Cloud_Spanner_to_GCS_Avro' \
--region=us-central1 \
--parameters='^|^instanceId=test-instance|databaseId=example-db|tableNames=table1,table2|outputDir=gs://my-gcs-bucket' \
--max-workers=10

shouldExportRelatedTables 参数是一个便捷的选择,可以自动导出所需表的所有父表。例如,在这个包含表 SingersAlbumsSongs架构层次结构中,我们只需要指定 SongsshouldExportRelatedTables 选项还会导出 SingersAlbums,因为 Songs 是这两者的后代。

gcloud dataflow jobs run my-export-job \
--gcs-location='gs://dataflow-templates/latest/Cloud_Spanner_to_GCS_Avro' \
--region=us-central1 \
--parameters='instanceId=test-instance,databaseId=example-db,tableNames=Songs,shouldExportRelatedTables=true,outputDir=gs://my-gcs-bucket' \
--max-workers=10

在 Dataflow 界面中查看作业或排查作业问题

启动导出作业后,您可以在 Google Cloud 控制台的 Dataflow 部分中查看作业的详细信息,包括日志。

查看 Dataflow 作业详情

如需查看过去一周内运行的任何导入/导出作业(包括当前正在运行的任何作业)的详细信息,请执行以下操作:

  1. 转到数据库的数据库概览页面。
  2. 点击左侧窗格中的导入/导出菜单项。数据库导入/导出页面会显示最近的作业列表。
  3. 在数据库导入/导出页面中,点击 Dataflow 作业名称列中的作业名称:

    运行中作业的状态消息

    Google Cloud 控制台会显示 Dataflow 作业的详细信息。

如需查看超过一周前运行的作业,请执行以下操作:

  1. 转到 Google Cloud 控制台中的 Dataflow 作业页面。

    转到作业页面

  2. 在列表中找到您的作业,然后点击其名称。

    Google Cloud 控制台会显示 Dataflow 作业的详细信息。

查看作业的 Dataflow 日志

如需查看 Dataflow 作业的日志,请按上文所述转到作业的详细信息页面,然后点击作业名称右侧的日志

如果作业失败,请查看日志了解错误。如果有错误,日志旁边会显示错误计数:

“日志”按钮旁边的错误计数示例

如需查看作业错误,请执行以下操作:

  1. 点击日志旁边的错误计数。

    Google Cloud 控制台会显示该作业的日志。您可能需要向下滚动才能看到错误。

  2. 找到带错误图标 “错误”图标 的条目。

  3. 点击各个日志条目以展开其内容。

如需详细了解如何对 Dataflow 作业进行问题排查,请参阅排查流水线问题

排查失败的导出作业问题

如果您在作业日志中看到以下错误,请执行以下操作:

com.google.cloud.spanner.SpannerException: NOT_FOUND: Session not found

--or--

com.google.cloud.spanner.SpannerException: DEADLINE_EXCEEDED: Deadline expired before operation could complete.

在 Google Cloud 控制台中,在 Spanner 数据库的 Monitoring 标签页中检查 99% 读取延迟时间。如果显示的值较大(几秒钟),则表示实例已过载,导致读取超时并失败。

导致高延迟的一个原因是 Dataflow 作业正在使用过多的工作器运行,给 Spanner 实例带来过多负载。

如需指定 Dataflow 工作器数量限制,您必须使用 Dataflow Cloud Spanner to Cloud Storage Avro 模板开始导出,而不是使用 Google Cloud 控制台中 Spanner 数据库的实例详情页面中的“导入/导出”标签页,并指定工作器数量上限,如下所述:
  • 如果您使用的是 Dataflow 控制台,则工作器数量上限参数位于基于模板创建作业页面上的可选参数部分。

  • 如果您使用的是 gcloud,请指定 max-workers 参数。例如:

    gcloud dataflow jobs run my-export-job \
    --gcs-location='gs://dataflow-templates/latest/Cloud_Spanner_to_GCS_Avro' \
    --region=us-central1 \
    --parameters='instanceId=test-instance,databaseId=example-db,outputDir=gs://my-gcs-bucket' \
    --max-workers=10
    

优化运行缓慢的导出作业

如果您已按照初始设置中的建议配置,则通常不必进行其他调整。如果作业运行缓慢,则可以尝试以下优化操作:

  • 优化作业和数据位置:在 Spanner 实例和 Cloud Storage 存储桶所在的同一区域运行 Dataflow 作业。

  • 确保有足够的 Dataflow 资源:如果相关 Compute Engine 配额限制了您的 Dataflow 作业的资源,则 Google Cloud 控制台中该作业的 Dataflow 页面会显示警告图标 警告图标 和日志消息:

    配额限制警告的屏幕截图

    在这种情况下,为 CPU、使用中的 IP 地址和标准永久性磁盘增加配额或许可以缩短作业的运行时间,但可能会因此产生更多的 Compute Engine 费用。

  • 检查 Spanner CPU 利用率:如果您发现某个实例的 CPU 利用率超过 65%,则可以增加该实例中的计算容量。容量增加的 Spanner 资源会增多,作业运行速度也会随之加快,但会产生更多的 Spanner 费用。

影响导出作业性能的因素

以下几个因素会影响完成导出作业所需的时间。

  • Spanner 数据库大小:处理的数据越多,需要的时间和资源也就越多。

  • Spanner 数据库架构,包括:

    • 表的数量
    • 行的大小
    • 二级索引的数量
    • 外键的数量
    • 变更数据流的数量

  • 数据位置:数据使用 Dataflow 在 Spanner 和 Cloud Storage 之间传输。理想情况下,这三个组件全都位于同一区域。如果这些组件不在同一区域,则跨区域移动数据会减慢作业运行速度。

  • Dataflow 工作器数量:最佳 Dataflow 工作器是实现良好性能所必需的。Dataflow 使用自动扩缩功能,根据需要完成的工作量选择作业的工作器数量。但是,工作器数量会受到 CPU、使用中的 IP 地址和标准永久性磁盘的配额的限制。如果工作器数量达到配额上限,Dataflow 界面中会显示一个警告图标。在这种情况下,运行速度会减慢,但作业仍会完成。

  • Spanner 上的现有负载:导出作业通常会给 Spanner 实例增加少量负载。如果该实例原本已有大量负载,则作业的运行速度会较慢。

  • Spanner 计算容量量:如果实例的 CPU 利用率超过 65%,则作业的运行速度会减慢。