为 Apache Iceberg 创建 BigLake 外部表
借助 BigLake 外部表,您可以采用只读格式访问具有更精细访问权限控制的 Apache Iceberg 表。此功能与适用于 Apache Iceberg 的 BigQuery 表不同,后者可让您采用可写格式在 BigQuery 中创建 Apache Iceberg 表。
Iceberg 是一种支持 PB 级数据表的开源表格式。Iceberg 的开放式规范让您能够对存储在对象存储区中的数据的单个副本运行多个查询引擎。适用于 Apache Iceberg 的 BigLake 外部表(以下简称 BigLake Iceberg 表)支持 Iceberg 规范版本 2,包括“读取时合并”功能。
作为 BigQuery 管理员,您可以强制执行行级和列级访问权限控制,包括对表执行数据遮盖。如需了解如何在表级层设置访问权限控制,请参阅设置访问权限控制政策。将 BigQuery Storage API 用作 Dataproc 和无服务器 Spark 中表的数据源时,也会强制执行表访问权限政策。此外,BigLake 表还可与其他 BigQuery 服务进行集成。如需查看可用集成的完整列表,请参阅 BigLake 表简介。
您可以采用以下方法创建 Iceberg BigLake 表:
使用 BigQuery Metastore(建议用于 Google Cloud)。BigQuery Metastore 基于 BigQuery 目录,并直接与 BigQuery 集成。BigQuery Metastore 中的表可通过多个开源引擎进行更改,并且可以通过 BigQuery 查询相同的表。BigQuery Metastore 还支持与 Apache Spark 直接集成。
使用 AWS Glue Data Catalog(建议用于 AWS)。建议您对 AWS 使用 AWS Glue,因为它是一个集中式元数据仓库,您可以在其中定义存储在各种 AWS 服务中的数据的结构和位置,并提供各种功能(例如自动架构发现以及与 AWS 分析工具的集成)。
使用 Iceberg JSON 元数据文件(建议用于 Azure)。如果使用 Iceberg JSON 元数据文件,则每当有表更新时,您都必须手动更新最新的元数据文件。您可以使用适用于 Apache Spark 的 BigQuery 存储过程来创建引用 Iceberg 元数据文件的 Iceberg BigLake 表。
如需查看相关限制的完整列表,请参阅限制。
准备工作
Enable the BigQuery Connection and BigQuery Reservation APIs.
如果您在 BigQuery 中使用 Spark 的存储过程来创建 Iceberg BigLake 表,则必须执行以下步骤:
如需将 Iceberg BigLake 表元数据和数据文件存储在 Cloud Storage 中,您还需创建 Cloud Storage 存储桶。您需要连接到该 Cloud Storage 存储桶才能访问元数据文件。请按以下步骤操作:
所需的角色
如需获得创建 BigLake 表所需的权限,请让管理员向您授予项目的以下 IAM 角色:
-
BigQuery Admin (
roles/bigquery.admin
) -
Storage Object Admin (
roles/storage.objectAdmin
)
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
这些预定义角色包含创建 BigLake 表所需的权限。如需查看所需的确切权限,请展开所需权限部分:
所需权限
如需创建 BigLake 表,需要以下权限:
-
bigquery.tables.create
-
bigquery.connections.delegate
-
bigquery.jobs.create
使用 BigQuery metastore 创建表
我们建议您使用 BigQuery Metastore 创建 Iceberg BigLake 表。您可以使用 Apache Spark 创建这些表。一种执行此操作的便捷方法是使用 BigQuery 存储过程。如需查看示例,请参阅创建和运行存储过程。
使用元数据文件创建表
您可以使用 JSON 元数据文件创建 BigLake Iceberg 表。但不建议使用这种方法,因为您必须手动更新 JSON 元数据文件的 URI 才能使 BigLake 表保持最新状态。如果 URI 未保持最新状态,BigQuery 中的查询可能会失败,或是导致提供的结果与直接使用 Iceberg 目录的其他查询引擎提供的结果不同。
系统将在您创建使用 Spark 的 Iceberg 表时指定的 Cloud Storage 存储桶中创建 Iceberg 表元数据文件。
从下列选项中选择一项:
SQL
使用 CREATE EXTERNAL TABLE
语句。 以下示例将创建一个名为 myexternal-table
的 BigLake 表:
CREATE EXTERNAL TABLE myexternal-table WITH CONNECTION `myproject.us.myconnection` OPTIONS ( format = 'ICEBERG', uris = ["gs://mybucket/mydata/mytable/metadata/iceberg.metadata.json"] )
将 uris
值替换为特定表快照的最新 JSON 元数据文件。
您可以通过设置 require_partition_filter
标志来启用需要分区过滤条件。
bq
在命令行环境中,将 bq mk --table
命令与 @connection
修饰器结合使用,指定要在 --external_table_definition
参数末尾使用的连接。如需启用需要分区过滤条件,请使用 --require_partition_filter
。
bq mk
--table
--external_table_definition=TABLE_FORMAT=URI@projects/CONNECTION_PROJECT_ID/locations/CONNECTION_REGION/connections/CONNECTION_ID
PROJECT_ID:DATASET.EXTERNAL_TABLE
替换以下内容:
TABLE_FORMAT
:要创建的表的格式在此示例中为
ICEBERG
。URI
:特定表快照的最新 JSON 元数据文件。例如
gs://mybucket/mydata/mytable/metadata/iceberg.metadata.json
。URI 也可以指向外部云端位置,例如 Amazon S3 或 Azure Blob Storage。
- AWS 示例:
s3://mybucket/iceberg/metadata/1234.metadata.json
。 - Azure 示例:
azure://mystorageaccount.blob.core.windows.net/mycontainer/iceberg/metadata/1234.metadata.json
。
- AWS 示例:
CONNECTION_PROJECT_ID
:包含用于创建 BigLake 表的连接的项目,例如myproject
CONNECTION_REGION
:包含用于创建 BigLake 表的连接的区域,例如us
CONNECTION_ID
:表连接 ID,例如myconnection
当您在 Google Cloud 控制台中查看连接详情时,连接 ID 是连接 ID 中显示的完全限定连接 ID 的最后一部分中的值,例如
projects/myproject/locations/connection_location/connections/myconnection
DATASET
:要在其中创建表的 BigQuery 数据集的名称例如
mydataset
。EXTERNAL_TABLE
:您要创建的表的名称例如
mytable
。
更新表元数据
如果您使用 JSON 元数据文件创建 BigLake Iceberg 表,请将表定义更新为最新表元数据。如需更新架构或元数据文件,请选择以下任一方法:
bq
创建表定义文件:
bq mkdef --source_format=ICEBERG \ "URI" > TABLE_DEFINITION_FILE
使用带有
--autodetect_schema
标志的bq update
命令。bq update --autodetect_schema --external_table_definition=TABLE_DEFINITION_FILE PROJECT_ID:DATASET.TABLE
替换以下内容:
URI
:包含最新 JSON 元数据文件的 Cloud Storage URI例如
gs://mybucket/us/iceberg/mytable/metadata/1234.metadata.json
。TABLE_DEFINITION_FILE
:包含表架构的文件的名称PROJECT_ID
:要更新的表所属的项目的 IDDATASET
:包含要更新的表的数据集TABLE
:要更新的表
API
使用 tables.patch
方法,并将 autodetect_schema
属性设置为 true
:
PATCH https://bigquery.googleapis.com/bigquery/v2/projects/PROJECT_ID/datasets/DATASET/tables/TABLE?autodetect_schema=true
替换以下内容:
PROJECT_ID
:要更新的表所属的项目的 IDDATASET
:包含要更新的表的数据集TABLE
:要更新的表
在请求正文中,为以下字段指定更新后的值:
{ "externalDataConfiguration": { "sourceFormat": "ICEBERG", "sourceUris": [ "URI" ] }, "schema": null }'
将 URI
替换为最新的 Iceberg 元数据文件。例如 gs://mybucket/us/iceberg/mytable/metadata/1234.metadata.json
。
设置访问权限控制政策
您可以使用多种方法来控制对 BigLake 表的访问权限:
例如,假设您要限制数据集 mydataset
中表 mytable
的行访问权限:
+---------+---------+-------+ | country | product | price | +---------+---------+-------+ | US | phone | 100 | | JP | tablet | 300 | | UK | laptop | 200 | +---------+---------+-------+
您可以为 Kim ([email protected]
) 创建行级过滤条件,限制其仅可访问 country
为 US
的行。
CREATE ROW ACCESS POLICY only_us_filter ON mydataset.mytable GRANT TO ('user:[email protected]') FILTER USING (country = 'US');
之后,Kim 运行以下查询:
SELECT * FROM projectid.mydataset.mytable;
输出将仅显示 country
为 US
的行:
+---------+---------+-------+ | country | product | price | +---------+---------+-------+ | US | phone | 100 | +---------+---------+-------+
查询 BigLake 表
如需了解详情,请参阅查询 Iceberg 数据。
数据映射
BigQuery 会将 Iceberg 数据类型转换为 BigQuery 数据类型,如下表所示:
Iceberg 数据类型 | BigQuery 数据类型 |
---|---|
boolean |
BOOL |
int |
INT64 |
long |
INT64 |
float |
FLOAT64 |
double |
FLOAT64 |
Decimal(P/S) |
NUMERIC or BIG_NUMERIC depending on precision |
date |
DATE |
time |
TIME |
timestamp |
DATETIME |
timestamptz |
TIMESTAMP |
string |
STRING |
uuid |
BYTES |
fixed(L) |
BYTES |
binary |
BYTES |
list<Type> |
ARRAY<Type> |
struct |
STRUCT |
map<KeyType, ValueType> |
ARRAY<Struct<key KeyType, value ValueType>> |
限制
除了 BigLake 表限制之外,Iceberg BigLake 表还具有以下限制:
使用“按读取合并”的表存在以下限制:
- 每个数据文件最多可以与 10,000 个删除文件相关联。
- 一个删除文件中最多只能应用 10 万个等式 ID。
- 您可以通过以下方法来规避这些限制:经常压缩删除文件,或者在 Iceberg 表上创建一个视图,以避免频繁更改分区。
BigQuery 支持使用所有 Iceberg 分区转换函数进行清单删减,但
Bucket
除外。如需了解如何删减分区,请参阅查询分区表。与分区列相比,引用 BigLake Iceberg 表的查询必须在谓词中包含字面量。仅支持 Apache Parquet 数据文件。
按需合并费用
按需结算的“按需合并”数据是以下数据扫描量的总和:
- 在数据文件中读取的所有逻辑字节(包括通过位置和等式删除标记为已删除的行)。
- 逻辑字节读取,用于加载等式删除文件和位置删除文件,以便在数据文件中查找已删除的行。
需要分区过滤条件
您可以通过为 Iceberg 表启用需要分区过滤条件选项来要求使用谓词过滤条件。如果启用此选项,则尝试在未指定与每个清单文件一致的 WHERE
子句的情况下查询表会产生以下错误:
Cannot query over table project_id.dataset.table without a filter that can be used for partition elimination.
每个清单文件都需要至少一个适合分区消除的谓词。
在创建 Iceberg 表时,您可以通过以下方式启用 require_partition_filter
:
SQL
使用 CREATE EXTERNAL TABLE
语句。以下示例会创建一个启用了需要分区过滤条件的 BigLake 表,名为 TABLE
:
CREATE EXTERNAL TABLE TABLE WITH CONNECTION `PROJECT_ID.REGION.CONNECTION_ID` OPTIONS ( format = 'ICEBERG', uris = [URI], require_partition_filter = true )
替换以下内容:
TABLE
:您要创建的表的名称。PROJECT_ID
:包含您要创建的表的项目的 ID。REGION
:您要在其中创建 Iceberg 表的位置。CONNECTION_ID
:连接 ID。例如myconnection
。URI
:包含最新 JSON 元数据文件的 Cloud Storage URI。例如
gs://mybucket/us/iceberg/mytable/metadata/1234.metadata.json
。URI 也可以指向外部云端位置,例如 Amazon S3 或 Azure Blob Storage。
- AWS 示例:
s3://mybucket/iceberg/metadata/1234.metadata.json
。 - Azure 示例:
azure://mystorageaccount.blob.core.windows.net/mycontainer/iceberg/metadata/1234.metadata.json
。
- AWS 示例:
bq
将 bq mk --table
命令与 @connection
修饰器结合使用,指定要在 --external_table_definition
参数末尾使用的连接。使用 --require_partition_filter
启用需要分区过滤条件。以下示例会创建一个启用了需要分区过滤条件的 BigLake 表,名为 TABLE
:
bq mk \ --table \ --external_table_definition=ICEBERG=URI@projects/CONNECTION_PROJECT_ID/locations/CONNECTION_REGION/connections/CONNECTION_ID \ PROJECT_ID:DATASET.EXTERNAL_TABLE \ --require_partition_filter
替换以下内容:
URI
:特定表快照的最新 JSON 元数据文件例如
gs://mybucket/mydata/mytable/metadata/iceberg.metadata.json
。URI 也可以指向外部云端位置,例如 Amazon S3 或 Azure Blob Storage。
- AWS 示例:
s3://mybucket/iceberg/metadata/1234.metadata.json
。 - Azure 示例:
azure://mystorageaccount.blob.core.windows.net/mycontainer/iceberg/metadata/1234.metadata.json
。
- AWS 示例:
CONNECTION_PROJECT_ID
:包含用于创建 BigLake 表的连接的项目,例如myproject
CONNECTION_REGION
:包含用于创建 BigLake 表的连接的区域。例如us
。CONNECTION_ID
:连接 ID。例如myconnection
。当您在 Google Cloud 控制台中查看连接详情时,连接 ID 是连接 ID 中显示的完全限定连接 ID 的最后一部分中的值,例如
projects/myproject/locations/connection_location/connections/myconnection
DATASET
:包含您要更新的表的BigQuery 数据集的名称。例如
mydataset
。EXTERNAL_TABLE
:要创建的表的名称例如
mytable
。
您还可以更新 Iceberg 表以启用需要分区过滤条件。
如果您在创建分区表时未启用需要分区过滤条件选项,则可以更新表来添加该选项。
bq
使用 bq update
命令并提供 --require_partition_filter
标志。
例如:
如需更新默认项目中 mydataset
的 mypartitionedtable
,请输入以下命令:
bq update --require_partition_filter PROJECT_ID:DATASET.TABLE
后续步骤
- 了解 Spark 的存储过程。
- 了解 BigLake 表。
- 了解访问权限控制政策。
- 了解如何在 BigQuery 中运行查询。
- 了解 BigQuery 中支持的语句和 SQL 方言。