为 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 功能。
准备工作
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the BigQuery Connection and BigQuery Reservation APIs.
-
In the Google Cloud console, activate Cloud Shell.
确保您有一个 BigQuery 数据集。
确保您的 Google Cloud SDK 为 366.0.0 版或更高版本:
gcloud version
如有需要,请更新 Google Cloud SDK。
根据外部数据源创建 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) |
NUMERIC 或 BIG_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 的数据集。