为 Delta Lake 创建 BigLake 外部表

借助 BigLake,您可以访问具有更精细访问权限控制的 Delta Lake 表。Delta Lake 是由 Databricks 开发的开源表格式数据存储格式,支持 PB 级数据表。

BigQuery 支持 Delta Lake 表的以下功能:

  • 访问权限委托:使用委托访问权限功能来查询外部数据存储区中的结构化数据。委托访问权限功能将对 Delta Lake 表的访问权限与对底层数据存储区的访问权限分离。
  • 精细的访问权限控制:在表级强制执行精细的安全措施,包括行级列级安全措施。对于基于 Cloud Storage 的 Delta Lake 表,您还可以使用动态数据遮盖
  • 架构演变:系统会自动检测 Delta Lake 表中的架构更改。架构更改会反映在 BigQuery 表中。

如果您将 Delta Lake 表配置为 BigLake 表,它们还支持所有 BigLake 功能。

准备工作

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the BigQuery Connection and BigQuery Reservation APIs.

    Enable the APIs

  4. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

  5. 确保您有一个 BigQuery 数据集

  6. 确保您的 Google Cloud SDK 为 366.0.0 版或更高版本:

    gcloud version
    

    如有需要,请更新 Google Cloud SDK

  7. 根据外部数据源创建 Cloud 资源连接,并向该连接授予对 Cloud Storage 的访问权限。如果您没有创建连接的适当权限,请让您的 BigQuery 管理员创建连接并与您共享。

所需的角色

如需创建 Delta Lake 表,您需要拥有以下权限:

  • bigquery.tables.create
  • bigquery.connections.delegate

BigQuery Admin (roles/bigquery.admin) 预定义的 Identity and Access Management 角色包含这些权限。

如果您不是此角色的主账号,请让您的管理员授予您这些权限或为您创建 Delta Lake 表。

此外,如需允许 BigQuery 用户查询表,与连接关联的服务账号必须具有以下权限和访问权限:

  • BigQuery Viewer (roles/bigquery.viewer) 角色
  • BigQuery Connection User (roles/bigquery.connectionUser) 角色
  • 访问包含这些数据的 Cloud Storage 存储桶

如需详细了解 BigQuery 中的 Identity and Access Management 角色和权限,请参阅预定义的角色和权限

使用 Delta Lake 创建表

如需创建 Delta Lake 表,请按以下步骤操作。

SQL

使用 CREATE EXTERNAL TABLE 语句创建 Delta Lake 表:

CREATE EXTERNAL TABLE `PROJECT_ID.DATASET.DELTALAKE_TABLE_NAME`
WITH CONNECTION `PROJECT_ID.REGION.CONNECTION_ID`
OPTIONS (
  format ="DELTA_LAKE",
  uris=['DELTA_TABLE_GCS_BASE_PATH']);

替换以下值:

  • PROJECT_ID:您要在其中创建 Delta Lake 表的项目的 ID
  • DATASET:包含 Delta Lake 表的 BigQuery 数据集
  • DELTALAKE_TABLE_NAME:Delta Lake 表的名称
  • REGION:包含用于创建 Delta Lake 表的连接的区域,例如 us
  • CONNECTION_ID:连接 ID,例如 myconnection

    当您在 Google Cloud 控制台中查看连接详情时,连接 ID 是连接 ID 中显示的完全限定连接 ID 的最后一部分中的值,例如 projects/myproject/locations/connection_location/connections/myconnection

  • DELTA_TABLE_GCS_BASE_PATH:Delta Lake 表前缀

bq

在命令行环境中,使用 bq mk 命令创建 Delta Lake 表:

bq mk --table --external_table_definition=DEFINITION_FILE PROJECT_ID:DATASET.DELTALAKE_TABLE_NAME

替换以下值:

  • DEFINITION_FILE:表定义文件的路径
  • PROJECT_ID:您要在其中创建 Delta Lake 表的项目的 ID
  • DATASET:包含 Delta Lake 表的 BigQuery 数据集
  • DELTALAKE_TABLE_NAME:Delta Lake 表的名称

REST

使用 BigQuery API 调用 tables.insert API 方法来创建 Delta Lake 表:

REQUEST='{
  "autodetect": true,
  "externalDataConfiguration": {
  "sourceFormat": "DELTA_LAKE",
  "connectionId": "PROJECT_ID.REGION.CONNECTION_ID",
  "sourceUris": [
    "DELTA_TABLE_GCS_BASE_PATH"
  ],
 },
"tableReference": {
"tableId": "DELTALAKE_TABLE_NAME"
}
}'

echo $REQUEST | curl -X POST -d @- -H "Content-Type: application/json" -H "Authorization: Bearer $(gcloud auth print-access-token)" https://bigquery.googleapis.com/bigquery/v2/projects/PROJECT_ID/datasets/DATASET/tables?autodetect_schema=true

替换以下值:

  • PROJECT_ID:您要在其中创建 Delta Lake 表的项目的 ID
  • REGION:包含用于创建 Delta Lake 表的连接的区域,例如 us
  • CONNECTION_ID:连接 ID,例如 myconnection

    当您在 Google Cloud 控制台中查看连接详情时,连接 ID 是连接 ID 中显示的完全限定连接 ID 的最后一部分中的值,例如 projects/myproject/locations/connection_location/connections/myconnection

  • DELTA_TABLE_GCS_BASE_PATH:Delta Lake 表前缀

  • DELTALAKE_TABLE_NAME:Delta Lake 表的名称

  • DATASET:包含 Delta Lake 表的 BigQuery 数据集

创建 Delta Lake 表时,Delta Lake 前缀将用作表的 URI。例如,对于在存储桶 gs://bucket/warehouse/basictable/_delta_log 中包含日志的表,表 URI 为 gs://bucket/warehouse/basictable。当您对 Delta Lake 表运行查询时,BigQuery 会读取该前缀下的相应数据以确定表的当前版本,然后计算表的元数据和文件。

虽然您无需连接即可创建 Delta Lake 外部表,但出于以下原因,我们不建议这样做:

  • 用户在尝试访问 Cloud Storage 中的文件时可能会遇到 ACCESS_DENIED 错误。
  • 精细访问权限控制等功能仅适用于 Delta Lake BigLake 表。

更新 Delta Lake 表

如需更新(刷新)Delta Lake 表的架构,请按以下步骤操作。

bq

在命令行环境中,使用 bq update 命令更新(刷新)Delta Lake 表的架构:

bq update --autodetect_schema PROJECT_ID:DATASET.DELTALAKE_TABLE_NAME

替换以下值:

  • PROJECT_ID:您要在其中创建 Delta Lake 表的项目的 ID
  • DATASET:包含 Delta Lake 表的 BigQuery 数据集
  • DELTALAKE_TABLE_NAME:Delta Lake 表的名称

REST

使用 BigQuery API 调用 tables.patch API 方法来更新 Delta Lake 表:

REQUEST='{
  "externalDataConfiguration": {
    "sourceFormat": "DELTA_LAKE",
    "sourceUris": [
      "DELTA_TABLE_GCS_BASE_PATH"
    ],
    "connectionId": "PROJECT_ID.REGION.CONNECTION_ID",
    "autodetect": true
  },
  "tableReference": {
    "tableId": "DELTALAKE_TABLE_NAME"
  }
}'
echo $REQUEST |curl -X POST -d @- -H "Content-Type: application/json" -H "Authorization: Bearer $(gcloud auth print-access-token)" https://bigquery.googleapis.com/bigquery/v2/projects/PROJECT_ID/datasets/DATASET/tables

替换以下值:

  • DELTA_TABLE_GCS_BASE_PATH:Delta Lake 表前缀
  • PROJECT_ID:您要在其中创建 Delta Lake 表的项目的 ID
  • REGION:包含用于创建 Delta Lake 表的连接的区域,例如 us
  • CONNECTION_ID:连接 ID,例如 myconnection

    当您在 Google Cloud 控制台中查看连接详情时,连接 ID 是连接 ID 中显示的完全限定连接 ID 的最后一部分中的值,例如 projects/myproject/locations/connection_location/connections/myconnection

  • DELTALAKE_TABLE_NAME:Delta Lake 表的名称

  • DATASET:包含 Delta Lake 表的 BigQuery 数据集

查询 Delta Lake 表

创建 Delta Lake BigLake 表后,您可以使用 GoogleSQL 语法查询表,就如查询标准 BigQuery 表一样。例如:

SELECT field1, field2 FROM mydataset.my_cloud_storage_table;

如需了解详情,请参阅查询 BigLake 表中的 Cloud Storage 数据

与服务账号关联的外部连接用于连接到数据存储区。由于服务账号会从数据存储区检索数据,因此用户只需访问 Delta Lake 表即可。

数据映射

BigQuery 会将 Delta Lake 数据类型转换为 BigQuery 数据类型,如下表所示:

Delta Lake 类型 BigQuery 类型
boolean BOOL
byte INT64
int INT64
long INT64
float FLOAT64
double FLOAT64
Decimal(P/S) NUMERICBIG_NUMERIC,具体取决于精度
date DATE
time TIME
timestamp (not partition column) TIMESTAMP
timestamp (partition column) DATETIME
string STRING
binary BYTES
array<Type> ARRAY<Type>
struct STRUCT
map<KeyType, ValueType> ARRAY<Struct<key KeyType, value ValueType>>

限制

除了 BigLake 表限制之外,Delta Lake 表还具有以下限制:

  • 支持 Delta Lake 读取器版本 3,其中包含删除向量和列映射。
  • 不支持 Delta Lake V2 检查点。
  • 您必须在最后一个日志条目文件中列出读取器版本。例如,新表必须包含 00000..0.json
  • 不支持变更数据捕获 (CDC) 操作。系统会忽略所有现有的 CDC 操作。
  • 架构是自动检测的。 不支持使用 BigQuery 修改架构。
  • 表列名称必须遵循 BigQuery 的列名称限制
  • 不支持具体化视图。
  • Delta Lake 不支持 Read API。

问题排查

本部分介绍了 Delta Lake BigLake 表。如需有关排查 BigQuery 查询问题的更一般性帮助,请参阅排查查询问题

查询超时和资源错误

检查 Delta Lake 表格的日志目录 (gs://bucket/warehouse/basictable/_delta_log),并查找版本号大于上一个检查点的 JSON 文件。您可以通过列出目录或检查 _delta_log/_last_checkpoint 文件来获取版本号。如果 JSON 文件大于 10 MiB,则可能会减慢表格展开速度,从而导致超时和资源问题。如需解决此问题,请使用以下命令创建新的检查点,以便查询跳过读取 JSON 文件:

  spark.sql("ALTER TABLE delta.`gs://bucket/mydeltatabledir` SET TBLPROPERTIES ('delta.checkpointInterval' = '1')");

然后,用户可以使用相同的命令将检查点间隔重置为默认值 10,或重置为一个值,以避免检查点之间的 JSON 文件超过 50 MB。

列名称无效

确保已为 Delta Lake 表开启列映射。Reader 2 或更高版本支持列映射。对于 Reader 版本 1,请使用以下命令将“delta.columnMapping.mode”设置为“name”:

spark.sql("ALTER TABLE delta.`gs://bucket/mydeltatabledir` SET TBLPROPERTIES ('delta.columnMapping.mode' = 'name', 'delta.minReaderVersion' = '3', 'delta.minWriterVersion' = '7')");

如果无效的列名称符合灵活的列名称限制,请与 Cloud Customer Care 联系或发送电子邮件至 biglake-help@google.com

访问被拒绝错误

如需诊断 Delta Lake BigLake 表存在的问题,请检查以下内容:

性能

如需提高查询性能,请尝试执行以下步骤:

  • 使用 Delta Lake 实用程序压缩底层数据文件并移除冗余文件(例如数据和元数据)。

  • 确保将 delta.checkpoint.writeStatsAsStruct 设置为 true

  • 确保在谓词子句中经常使用的变量位于分区列中。

大型数据集(大于 100 TB)可能需要额外的配置和功能。如果上述步骤未能解决问题,不妨考虑与客户服务团队biglake-help@google.com 联系,尤其是对于大于 100 TB 的数据集。