复制数据集

您可以在同一区域内或跨区域复制数据集,而无需提取、移动并将数据重新加载到 BigQuery 中。您可以一次性复制数据集,也可以执行自定义的周期性复制。

准备工作

在创建数据集副本之前,请先做好以下准备工作:

  • 数据集复制要使用 BigQuery Data Transfer Service 的功能。请在目标数据集所属的 Google Cloud 项目中,确认您是否已完成启用 BigQuery Data Transfer Service 所需的所有操作。
  • 创建 BigQuery 数据集,作为目标数据集,该数据集可以与源数据集位于同一区域也可以位于不同区域。创建数据集时,请指定 BigQuery 数据的存储位置。并非所有区域都支持数据集复制(请参阅支持的区域)。每个项目中的数据集名称必须唯一。
  • 找到要复制的源数据集的 ID 以及源项目的 ID。
  • 如果您要设置 Pub/Sub 的转移作业运行通知,必须拥有 pubsub.topics.setIamPolicy 权限。如果您只是要设置电子邮件通知,则无需 Pub/Sub 权限。如需了解详情,请参阅 BigQuery Data Transfer Service 运行通知
  • 如果您打算在使用 overwrite_destination_table 标志进行复制时覆盖目标表,则两个表必须具有相同的分区架构。

所需权限

在创建数据集副本之前,请确保创建数据集副本的人员在 BigQuery 中拥有以下权限:

  • 针对项目的 bigquery.transfers.updatebigquery.jobs.create 权限,创建副本转移作业所需。

  • 针对源数据集的 bigquery.datasets.get 权限。

  • 针对目标数据集的 bigquery.datasets.getbigquery.datasets.updatebigquery.tables.create 权限。

预定义的项目级层 IAM 角色 bigquery.admin 可提供针对数据集副本的所有必要权限。如需详细了解 BigQuery 中的 IAM 角色,请参阅预定义角色和权限IAM 权限参考文档

设置数据集副本

如需创建数据集副本,请执行以下操作:

控制台

方法 1:使用复制数据集图标。

  1. 转到 Cloud Console 中的 BigQuery 页面。

    转到 BigQuery 页面

  2. 选择要复制的源数据集的名称。

  3. 点击复制数据集图标。

    “复制数据集”图标。

  4. 复制数据集对话框中,选择项目 ID 和目标数据集 ID。项目和数据集可以位于不同区域,但并非所有区域都支持跨区域的数据集复制

  5. 项目中的数据集名称必须唯一。

  6. (可选)如果要刷新(覆盖)目标数据集中的所有数据,请勾选覆盖目标表 (Overwrite destination table) 复选框。表和架构都会被覆盖。

    “复制数据集”对话框。

  7. 请考虑删除旧数据集以避免额外的存储开销。

方法 2:使用转移作业按钮。

  1. 转到 Cloud Console 中的 BigQuery 页面。

    转到 BigQuery 页面

  2. 点击转移作业

  3. 点击 + 创建转移作业

  4. 创建转移作业页面上:

    • 来源类型部分的来源中,选择数据集副本 (Dataset Copy)。

      转移作业来源。

    • 转移配置名称部分的显示名中,输入转移作业的名称,例如 My Transfer。转移作业名称可以是任何容易辨识的值,让您以后在需要修改转移作业时能够轻松识别。

      转移作业名称。

    • 时间表选项部分的时间表中,保留默认值(立即开始)或点击在设置的时间开始 (Start at a set time)。

      • 重复频率部分中,选择转移作业的运行频率选项。 选项包括:

        • 每日一次(默认值)
        • 每周一次
        • 每月一次
        • 自定义
        • 按需

        如果您选择除每日一次以外的选项,则系统还会提供其他选项。例如,如果您选择每周一次,则系统会显示一个选项,供您选择星期几。如果选择自定义,应以类似 Cron 的时间规格输入间隔时间,例如 every 12 hours。允许的最短间隔时间为 12 小时。

      • 开始日期和运行时间部分,输入开始转移作业的日期和时间。如果选择立即开始,则无法修改此字段。

        转移作业时间表。

    • 目标数据集部分,选择您在另一个区域中创建用于存储数据的数据集。

    • 源数据集部分,输入要复制的数据集的名称。

    • 源项目部分,输入源数据集所在项目的 ID。

    • (可选)如果要刷新(覆盖)目标数据集中的所有数据,请勾选覆盖目标表 (Overwrite destination table) 复选框。表和架构都会被覆盖。

      新建数据集副本。

    • (可选)在通知选项部分,执行以下操作:

      • 点击切换开关以启用电子邮件通知。启用此选项后,转移作业管理员会在转移作业运行失败时收到电子邮件通知。
      • 选择 Pub/Sub 主题部分,选择您的主题名称,或点击创建主题来创建一个主题。此选项用于为您的转移作业配置 Pub/Sub 运行通知

      Pub/Sub 主题。

  5. 点击保存

  6. 请考虑删除旧数据集以避免额外的存储开销。

bq

输入 bq mk 命令并提供转移作业创建标志 --transfer_config。此外,还必须提供以下标志:

  • --project_id
  • --data_source
  • --target_dataset
  • --display_name
  • --params

    bq mk --transfer_config --project_id=PROJECT_ID --data_source=DATA_SOURCE --target_dataset=DATASET --display_name=NAME --params='PARAMETERS'
    

替换以下内容:

  • PROJECT_ID:您的 Google Cloud 项目 ID。如果未指定 --project_id,系统会使用默认项目。
  • DATA_SOURCE:数据源:cross_region_copy
  • DATASET:转移作业配置的 BigQuery 目标数据集。
  • NAME:复制作业或转移作业配置的显示名。转移作业名称可以是任何容易辨识的值,让您以后在需要修改转移作业时能够轻松识别。
  • PARAMETERS 包含所创建转移作业配置的参数(采用 JSON 格式),例如 --params='{"param":"param_value"}'。对于数据集复制,您必须提供 source_dataset_idsource_project_id 参数,并视情况提供 overwrite_destination_table 参数。

数据集副本配置包括以下参数:

  • source_dataset_id:要复制的源数据集的 ID。
  • source_project_id:源数据集所在项目的 ID。
  • (可选)overwrite_destination_table:如果您要截断前一个副本的表并刷新所有数据,请添加此参数。

例如,以下命令会创建名为 My Transfer 的数据集副本配置,其中目标数据集名为 mydataset 且项目 ID 为 myproject

bq mk --transfer_config --project_id=myproject --data_source=cross_region_copy --target_dataset=mydataset --display_name='My Dataset Copy' --params='{"source_dataset_id":"123_demo_eu","source_project_id":"mysourceproject","overwrite_destination_table":"true"}'

如需详细了解 bq mk 命令,请参阅命令行工具参考文档

API

使用 projects.locations.transferConfigs.create 方法并提供一个 TransferConfig 资源实例。

Java

试用此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Java 设置说明进行操作。 如需了解详情,请参阅 BigQuery Java API 参考文档

import com.google.api.gax.rpc.ApiException;
import com.google.cloud.bigquery.datatransfer.v1.CreateTransferConfigRequest;
import com.google.cloud.bigquery.datatransfer.v1.DataTransferServiceClient;
import com.google.cloud.bigquery.datatransfer.v1.ProjectName;
import com.google.cloud.bigquery.datatransfer.v1.TransferConfig;
import com.google.protobuf.Struct;
import com.google.protobuf.Value;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

// Sample to copy dataset from another gcp project
public class CopyDataset {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    final String destinationProjectId = "MY_DESTINATION_PROJECT_ID";
    final String destinationDatasetId = "MY_DESTINATION_DATASET_ID";
    final String sourceProjectId = "MY_SOURCE_PROJECT_ID";
    final String sourceDatasetId = "MY_SOURCE_DATASET_ID";
    Map<String, Value> params = new HashMap<>();
    params.put("source_project_id", Value.newBuilder().setStringValue(sourceProjectId).build());
    params.put("source_dataset_id", Value.newBuilder().setStringValue(sourceDatasetId).build());
    TransferConfig transferConfig =
        TransferConfig.newBuilder()
            .setDestinationDatasetId(destinationDatasetId)
            .setDisplayName("Your Dataset Copy Name")
            .setDataSourceId("cross_region_copy")
            .setParams(Struct.newBuilder().putAllFields(params).build())
            .setSchedule("every 24 hours")
            .build();
    copyDataset(destinationProjectId, transferConfig);
  }

  public static void copyDataset(String projectId, TransferConfig transferConfig)
      throws IOException {
    try (DataTransferServiceClient dataTransferServiceClient = DataTransferServiceClient.create()) {
      ProjectName parent = ProjectName.of(projectId);
      CreateTransferConfigRequest request =
          CreateTransferConfigRequest.newBuilder()
              .setParent(parent.toString())
              .setTransferConfig(transferConfig)
              .build();
      TransferConfig config = dataTransferServiceClient.createTransferConfig(request);
      System.out.println("Copy dataset created successfully :" + config.getName());
    } catch (ApiException ex) {
      System.out.print("Copy dataset was not created." + ex.toString());
    }
  }
}

Python

在尝试此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Python 设置说明进行操作。如需了解详情,请参阅 BigQuery Python API 参考文档

使用 pip install google-cloud-bigquery-datatransfer 安装适用于 BigQuery Data Transfer API 的 Python 客户端。然后创建转移作业配置以复制数据集。
from google.cloud import bigquery_datatransfer

transfer_client = bigquery_datatransfer.DataTransferServiceClient()

destination_project_id = "my-destination-project"
destination_dataset_id = "my_destination_dataset"
source_project_id = "my-source-project"
source_dataset_id = "my_source_dataset"
transfer_config = bigquery_datatransfer.TransferConfig(
    destination_dataset_id=destination_dataset_id,
    display_name="Your Dataset Copy Name",
    data_source_id="cross_region_copy",
    params={
        "source_project_id": source_project_id,
        "source_dataset_id": source_dataset_id,
    },
    schedule="every 24 hours",
)
transfer_config = transfer_client.create_transfer_config(
    parent=transfer_client.common_project_path(destination_project_id),
    transfer_config=transfer_config,
)
print(f"Created transfer config: {transfer_config.name}")

查看和刷新数据集副本作业

您可以在转移作业下查看数据集复制作业的进度和详细信息。

控制台

转移作业按钮控制台。

查看转移作业详情控制台。

系统会按照您指定的时间表运行数据集副本刷新,该时间表可进行配置。默认为每 24 小时运行一次。如果您想要请求立即执行新运行,请点击更多菜单,然后点击立即刷新

刷新数据集副本按钮。

价格

测试版的数据集复制是免费的。

正式版发布后,各区域间复制数据将按照各区域间的 Compute Engine 网络出站流量的价格计费。

BigQuery 会发送经压缩的数据以进行跨区域复制,因此计费的 GB 数可能小于数据集的大小。

配额和限制

以下限制适用于在 BigQuery 中复制数据集。这些限制适用于使用 bq 命令行工具或 Cloud Console 创建的复制作业,以及使用复制类型的 jobs.insert API 方法以编程方式提交的复制作业。

针对存储和查询的所有 BigQuery 使用量标准收费同样适用于复制的数据。如需了解详情,请参阅价格

BigQuery 数据集副本存在如下限制。

配额

区域内

在同一区域内复制数据集时,所有 BigQuery 复制作业均使用同一配额。

以下限制适用于在 BigQuery 中复制表的情况。这些限制适用于使用 bq 命令行工具或 Cloud Console 复制数据时自动创建的作业,以及使用复制类型 jobs.insert API 方法以编程方式提交的复制作业。

  • 每个目标表每天的复制作业数 - 1000 个(包括失败的作业)
  • 每个项目每天的复制作业数 - 100000 个(包括失败的作业)

跨区域

  • 每个目标表每天的复制作业数:100 个(包括失败的作业)
  • 每个项目每天的复制作业数:2000 个(包括失败的作业)

一般限制

  • 您必须先创建目标数据集,然后才能创建用于数据集复制的转移作业配置。

  • 对于每个数据集副本配置,您一次只能有一个有效副本。其他转移作业运行会被排入队列。

数据类型限制

  • 不支持复制视图。
  • 不支持复制外部表。
  • 不支持在流式缓冲区中复制存储。
  • 对于使用客户管理的密钥加密的表,是否支持复制取决于您是在同一区域内复制还是跨区域进行复制。

区域内

对于在同一区域内的数据集复制,支持复制加密表(包括使用客户管理的密钥 (CMEK) 加密的表)。

跨区域

对于使用默认加密的表,支持跨区域复制。 但目前尚不支持跨区域复制使用客户管理的密钥 (CMEK) 加密的表。将表复制到目标数据集时,系统将跳过 CMEK 加密的表。

源数据集限制

源数据集中最多可以包含 20000 个表。每次运行可复制的表数量取决于同一区域内复制还是跨区域复制。

区域内

  • 源数据集中最多可以包含 20000 个表。

  • 每次运行最多可以将 20000 个表复制到目标数据集。

跨区域

  • 源数据集中最多可以包含 20000 个表。

  • 每次运行时最多可以将 1000 张表复制到目标数据集。

示例

如果您为包含 8000 个表的数据集配置了跨区域复制,则 BigQuery Data Transfer Service 会按顺序自动创建 8 次运行。第一次运行将复制 1000 个表,24 小时后另一次运行会再复制 1000 个表,以此类推,直到复制完数据集中的所有表为止。每个数据集中最多可包含 20000 个表。

目标数据集限制

跨区域

在跨区域复制时,包含客户管理的密钥 (CMEK) 的数据集不能用作目标。但是,在区域之间复制时,可以将具有 CMEK 的表作为目标。

表限制

  • 目前支持复制分区表。但是,不支持将数据附加到分区表。

  • 如果某个表在源数据集和目标数据集中都存在,并且自上次成功复制后该表未发生更改,则系统会跳过复制该表。即使勾选了覆盖目标表 (Override destination table) 复选框也是如此。

  • 截断表时,开始复制之前数据集复制不会检测目标数据集是否有任何更改。系统会刷新(覆盖)目标数据集中的所有数据。表和架构都会被覆盖。

    • 如果您打算在使用 overwrite_destination_table 标志进行复制时覆盖目标表,则两个表必须具有相同的分区架构。

支持的区域

位置具有两种类型:

  • 单区域位置是具体的地理位置,如伦敦。

  • 多区域位置是至少包含两个地理位置的大型地理区域,如美国。

您可以将数据集从一个区域复制到另一个区域、从单个区域复制到多个区域、从多个区域复制到单个区域,或从多个区域复制到多个区域。

目前并非所有区域都支持进行数据集复制。您可以在目前支持 BigQuery Data Transfer Service 的区域内创建数据集副本,如下所示。

区域位置

区域说明 单区域名称
美洲
爱荷华 us-central1
拉斯维加斯 us-west4
洛杉矶 us-west2
蒙特利尔 northamerica-northeast1
北弗吉尼亚 us-east4
俄勒冈 us-west1
盐湖城 us-west3
圣保罗 southamerica-east1
南卡罗来纳 us-east1
欧洲
比利时 europe-west1
芬兰 europe-north1
法兰克福 europe-west3
伦敦 europe-west2
荷兰 europe-west4
华沙 europe-central2
苏黎世 europe-west6
亚太地区
香港 asia-east2
雅加达 asia-southeast2
孟买 asia-south1
大阪 asia-northeast2
首尔 asia-northeast3
新加坡 asia-southeast1
悉尼 australia-southeast1
台湾 asia-east1
东京 asia-northeast1

多区域位置

多区域说明 多区域名称
欧盟成员国的数据中心1 EU
美国的数据中心 US

1 位于 EU 多区域的数据不会存储在 europe-west2(伦敦)或 europe-west6(苏黎世)数据中心中。

后续步骤

  • 如需详细了解如何使用转移作业,包括获取有关转移作业配置的信息、列出转移作业配置以及查看转移作业的运行历史记录,请参阅处理转移作业