本文档简要介绍了 BigQuery 订阅、其工作流和相关属性。
BigQuery 订阅是一种导出订阅,可在收到消息时将其写入现有 BigQuery 表。您无需配置单独的订阅方客户端。 您可以使用 Google Cloud 控制台、Google Cloud CLI、客户端库或 Pub/Sub API 来创建、更新、列出、分离或删除 BigQuery 订阅。
如果不使用 BigQuery 订阅类型,您需要拉取或推送订阅以及订阅者(例如 Dataflow)以读取消息并将其写入 BigQuery 表。如果消息在存储到 BigQuery 表之前不需要进行额外处理,则无需运行 Dataflow 作业,而是可以使用 BigQuery 订阅。
不过,对于需要在将数据存储到 BigQuery 表之前进行一些数据转换的 Pub/Sub 系统,我们仍建议使用 Dataflow 流水线。如需了解如何使用 Dataflow 将数据从 Pub/Sub 流式传输到 BigQuery 并进行转换,请参阅从 Pub/Sub 流式传输到 BigQuery。
Dataflow 中的 Pub/Sub 订阅到 BigQuery 模板默认强制执行“正好一次”传送。这通常通过 Dataflow 流水线中的重复数据删除机制来实现。不过,BigQuery 订阅仅支持至少传送一次。如果您的使用场景对精确去重至关重要,请考虑在 BigQuery 中使用下游流程来处理潜在的重复项。
准备工作
在阅读本文档之前,请确保您熟悉以下内容:
Pub/Sub 的工作原理以及不同的 Pub/Sub 术语。
Pub/Sub 支持的不同订阅类型,以及您可能需要使用 BigQuery 订阅的原因。
BigQuery 的运作方式,以及如何配置和管理 BigQuery 表。
BigQuery 订阅工作流
下图显示了 BigQuery 订阅和 BigQuery 之间的工作流。

下面简要介绍了图 1 中所示的工作流程:
- Pub/Sub 使用 BigQuery Storage Write API 将数据发送到 BigQuery 表。
- 消息会分批发送到 BigQuery 表。
- 写入操作成功完成后,API 会返回“确定”响应。
- 如果写入操作中出现任何失败,Pub/Sub 消息本身会被否定确认。然后重新发送消息。如果消息失败次数足够多,并且订阅中配置了死信主题,则该消息会被移至死信主题。
BigQuery 订阅的属性
您为 BigQuery 订阅配置的属性决定了 Pub/Sub 将消息写入的 BigQuery 表以及该表的架构类型。
如需了解详情,请参阅 BigQuery 属性。
架构兼容性
仅当您在创建 BigQuery 订阅时选择使用主题架构选项时,本部分才适用。
Pub/Sub 和 BigQuery 使用不同的方式来定义其架构。Pub/Sub 架构以 Apache Avro 或 Protocol Buffer 格式定义,而 BigQuery 架构则使用多种格式定义。
以下是有关 Pub/Sub 主题与 BigQuery 表之间的架构兼容性的重要信息列表。
任何包含格式不正确的字段的消息都不会写入 BigQuery。
在 BigQuery 架构中,
INT
、SMALLINT
、INTEGER
、BIGINT
、TINYINT
和BYTEINT
是INTEGER
的别名;DECIMAL
是NUMERIC
的别名;BIGDECIMAL
是BIGNUMERIC
的别名。如果主题架构中的类型为
string
,而 BigQuery 表中的类型为JSON
、TIMESTAMP
、DATETIME
、DATE
、TIME
、NUMERIC
或BIGNUMERIC
,则 Pub/Sub 消息中相应字段的任何值都必须遵循为 BigQuery 数据类型指定的格式。系统支持某些 Avro 逻辑类型,如下表所示。 未列出的任何逻辑类型仅匹配它们注释的等效 Avro 类型,如 Avro 规范中所述。
以下是不同架构格式与 BigQuery 数据类型的映射关系集合。
Avro 类型
Avro 类型 | BigQuery 数据类型 |
null |
Any NULLABLE |
boolean |
BOOLEAN |
int |
INTEGER 、NUMERIC 或 BIGNUMERIC |
long |
INTEGER 、NUMERIC 或 BIGNUMERIC |
float |
FLOAT64 、NUMERIC 或 BIGNUMERIC |
double |
FLOAT64 、NUMERIC 或 BIGNUMERIC |
bytes |
BYTES 、NUMERIC 或 BIGNUMERIC |
string |
STRING 、JSON 、TIMESTAMP 、DATETIME 、DATE 、TIME 、NUMERIC 或 BIGNUMERIC |
record |
RECORD/STRUCT |
array /Type |
REPEATED Type |
map ,值类型为 ValueType
|
REPEATED STRUCT <key STRING, value
ValueType> |
具有两种类型的 union ,一种是 null ,另一种是 Type |
NULLABLE Type |
其他 union |
无法映射 |
fixed |
BYTES 、NUMERIC 或 BIGNUMERIC |
enum |
INTEGER |
Avro 逻辑类型
Avro 逻辑类型 | BigQuery 数据类型 |
timestamp-micros |
TIMESTAMP |
date |
DATE |
time-micros |
TIME |
duration |
INTERVAL |
decimal |
NUMERIC 或 BIGNUMERIC |
协议缓冲区类型
协议缓冲区类型 | BigQuery 数据类型 |
double |
FLOAT64 、NUMERIC 或 BIGNUMERIC |
float |
FLOAT64 、NUMERIC 或 BIGNUMERIC |
int32 |
INTEGER 、NUMERIC 、BIGNUMERIC 或 DATE |
int64 |
INTEGER 、NUMERIC 、BIGNUMERIC 、DATE 、DATETIME 或 TIMESTAMP |
uint32 |
INTEGER 、NUMERIC 、BIGNUMERIC 或 DATE |
uint64 |
NUMERIC 或 BIGNUMERIC |
sint32 |
INTEGER 、NUMERIC 或 BIGNUMERIC |
sint64 |
INTEGER 、NUMERIC 、BIGNUMERIC 、DATE 、DATETIME 或 TIMESTAMP |
fixed32 |
INTEGER 、NUMERIC 、BIGNUMERIC 或 DATE |
fixed64 |
NUMERIC 或 BIGNUMERIC |
sfixed32 |
INTEGER 、NUMERIC 、BIGNUMERIC 或 DATE |
sfixed64 |
INTEGER 、NUMERIC 、BIGNUMERIC 、DATE 、DATETIME 或 TIMESTAMP |
bool |
BOOLEAN |
string |
STRING 、JSON 、TIMESTAMP 、DATETIME 、DATE 、TIME 、NUMERIC 或 BIGNUMERIC |
bytes |
BYTES 、NUMERIC 或 BIGNUMERIC |
enum |
INTEGER |
message |
RECORD/STRUCT |
oneof |
无法映射 |
map<KeyType, ValueType> |
REPEATED RECORD<key KeyType, value
ValueType> |
enum |
INTEGER |
repeated/array of Type |
REPEATED Type |
日期和时间整数表示法
从整数映射到某个日期或时间类型时,该数字必须表示正确的值。以下是从 BigQuery 数据类型到表示它们的整数的映射。
BigQuery 数据类型 | 整数表示法 |
DATE |
自 Unix 纪元(1970 年 1 月 1 日)以来的天数 |
DATETIME |
以微秒为单位的日期和时间,使用 CivilTimeEncoder 表示为民用时间 |
TIME |
以微秒为单位的时间,使用 CivilTimeEncoder 表示为民用时间 |
TIMESTAMP |
自 Unix 纪元(1970 年 1 月 1 日 00:00:00 UTC)以来的微秒数 |
BigQuery 变更数据捕获
当订阅属性中的 use_topic_schema
或 use_table_schema
设置为 true
时,BigQuery 订阅支持变更数据捕获 (CDC) 更新。如需将此功能与 use_topic_schema
搭配使用,请使用以下字段设置主题的架构:
_CHANGE_TYPE
(必需):设置为UPSERT
或DELETE
的string
字段。如果写入 BigQuery 表的 Pub/Sub 消息的
_CHANGE_TYPE
设置为UPSERT
,则 BigQuery 会更新具有相同键的行(如果存在),否则会插入新行。如果写入 BigQuery 表的 Pub/Sub 消息的
_CHANGE_TYPE
设置为DELETE
,则 BigQuery 会删除表中具有相同键的行(如果存在)。
_CHANGE_SEQUENCE_NUMBER
(可选):设置为string
的字段,用于确保对 BigQuery 表进行的更新和删除按顺序处理。对于同一行键,消息必须包含单调递增的_CHANGE_SEQUENCE_NUMBER
值。序列号小于为某行处理的最高序列号的消息不会对 BigQuery 表中的相应行产生任何影响。序列号必须遵循_CHANGE_SEQUENCE_NUMBER
格式。
如需将此功能与 use_table_schema
搭配使用,请在 JSON 消息中添加上述字段。
如需了解 CDC 价格,请参阅 CDC 价格。
BigQuery 中的 Apache Iceberg BigLake 表
BigQuery 订阅可与 BigQuery 中适用于 Apache Iceberg 的 BigLake 表搭配使用,无需进行任何额外更改。
适用于 Apache Iceberg 的 BigQuery BigLake 表为在 Google Cloud上构建开放格式湖仓一体提供了基础。这些表提供与标准(内置)BigQuery 表相同的全代管式体验,但使用 Parquet 将数据存储在客户拥有的存储分区中,以便与 Iceberg 开放表格式进行互操作。
如需了解如何在 BigQuery 中创建适用于 Apache Iceberg 的 BigLake 表,请参阅创建 Iceberg 表。
处理消息故障
当 Pub/Sub 消息无法写入 BigQuery 时,该消息无法得到确认。如需转发此类无法递送的消息,请在 BigQuery 订阅中配置死信主题。转发到死信主题的 Pub/Sub 消息包含一个属性 CloudPubSubDeadLetterSourceDeliveryErrorMessage
,其中包含 Pub/Sub 消息无法写入 BigQuery 的原因。
如果 Pub/Sub 无法将消息写入 BigQuery,则 Pub/Sub 会以类似于推送退避行为的方式退避消息传送。不过,如果订阅附加了死信主题,那么当消息失败是由于架构兼容性错误所致时,Pub/Sub 不会退避传送。
配额和限制
每个区域的 BigQuery 订阅者吞吐量都有配额限制。如需了解详情,请参阅 Pub/Sub 配额和限制。
BigQuery 订阅使用 BigQuery Storage Write API 写入数据。如需了解 Storage Write API 的配额和限制,请参阅 BigQuery Storage Write API 请求。BigQuery 订阅仅会消耗 Storage Write API 的吞吐量配额。在这种情况下,您可以忽略其他 Storage Write API 配额注意事项。
价格
如需了解 BigQuery 订阅的价格,请参阅 Pub/Sub 价格页面。
后续步骤
创建订阅,例如 BigQuery 订阅。
排查 BigQuery 订阅方面的问题。
阅读有关 BigQuery 的文章。
查看 Pub/Sub 的价格,包括 BigQuery 订阅。
使用
gcloud
CLI 命令创建或修改订阅。使用 REST API 创建或修改订阅。