排查 BigQuery Storage API 错误
本文档介绍了在使用 BigQuery Storage Read API、BigQuery Storage Write API (gRPC) 或通过 BigQuery Storage Write API (REST)(tabledata.insertAll 方法)进行流式插入时,如何排查 BigQuery 中的数据读取或流式传输问题。
使用 INFORMATION_SCHEMA 视图分析流式遥测数据
您可以查询 INFORMATION_SCHEMA 视图,以监控流式注入的健康状况、发现吞吐量瓶颈,并检查一分钟间隔内的错误代码:
- Storage Write API (gRPC):查询
INFORMATION_SCHEMA.WRITE_API_TIMELINE视图,以检查 gRPC 流式注入请求、附加的总字节数和行数,以及按error_code划分的错误计数。 - Storage Write API (REST):查询
INFORMATION_SCHEMA.STREAMING_TIMELINE视图,以检查旧版 RESTtabledata.insertAll流式传输请求和配额或速率限制错误。
以下示例查询 INFORMATION_SCHEMA.WRITE_API_TIMELINE_BY_PROJECT,以检索过去 24 小时内 Storage Write API (gRPC) 的错误计数和注入的字节数:
SELECT start_timestamp, error_code, SUM(total_requests) AS request_count, SUM(total_input_bytes) AS input_bytes FROM `region-REGION`.INFORMATION_SCHEMA.WRITE_API_TIMELINE_BY_PROJECT WHERE start_timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY) AND error_code IS NOT NULL GROUP BY start_timestamp, error_code ORDER BY start_timestamp DESC;
将 REGION 替换为数据集区域名称,例如 us 或 europe-west1。
排查 Storage Read API 错误
以下是使用 Storage Read API 时遇到的常见错误:
- 错误:
Stream removed - 解决方法:重试 Storage Read API 请求。这很可能是一个暂时性错误,您可以通过重试请求来解决。如果问题仍然存在,请与 Cloud Customer Care 联系。
- 错误:
Stream expired 原因:当 Storage Read API 会话达到 6 小时超时时间时,就会发生此错误。
解决方法:
- 提高作业的并行度。
- 如果工作器节点的 CPU 利用率相对稳定且不超过 85%,请考虑在更大的机器类型上运行作业。
- 将作业拆分为多个作业或更小的查询。
如需详细了解会话管理和数据读取,请参阅 Storage Read API 概览。
排查流式插入问题
以下部分讨论如何排查在使用 Storage Write API (REST) 将数据流式插入到 BigQuery 时发生的错误。如需详细了解如何解决流式插入的配额错误,请参阅流式插入配额错误。
失败 HTTP 响应代码
如果收到失败的 HTTP 响应代码(如网络连接错误),则无法确定流式插入是否成功。如果您尝试重新发送请求,则可能导致最终表中出现重复的行。为了避免表中出现重复的内容,请在发送请求时设置 insertId 属性。BigQuery 使用 insertId 属性进行去重。
如果您收到权限错误、无效的表名称错误或超出配额错误,则不会插入任何行,并且整个请求都会失败。
成功 HTTP 响应代码
即使您收到成功 HTTP 响应代码,也必须检查响应的 insertErrors 属性才能确定是否成功插入行,因为 BigQuery 可能只是成功插入了部分行。您可能会遇到以下情况之一:
- 所有行均已成功插入:如果
insertErrors属性是空列表,则表示所有行均已成功插入。 - 已成功插入一些行:除非任何行中存在架构不匹配的情况,否则
insertErrors属性中指示的行不会插入,而其他所有行则会成功插入。errors属性详细说明了每个未成功插入行的失败原因。index属性指示请求中与错误对应的行索引(从 0 开始)。 - 未成功插入任何行:如果 BigQuery 在请求的个别行上遇到架构不匹配的情况,则系统不会插入任何行,并会针对每一行(即使是架构匹配的行)返回一个
insertErrors条目。对于架构匹配的行,其所对应错误的reason属性将设置为stopped,因此您可以按原样重新发送这些行。而对于插入失败的行,其会包含有关架构不匹配情况的详细信息。如需了解每种 BigQuery 数据类型支持的协议缓冲区类型,请参阅支持的协议缓冲区和 Arrow 数据类型。
流式插入的元数据错误
由于 BigQuery Streaming API 旨在实现高插入速率,因此在与流式传输系统交互时,对底层表元数据的修改最终会保持一致。大多数情况下,元数据更改会在几分钟内传播,但在此期间,API 响应可能会反映表的不一致状态。
以下是一些应用场景:
- 架构更改:针对最近接收了流式插入内容的表修改架构时,响应可能会指出架构不匹配错误,因为流式插入系统可能不会立即检测到架构更改。
- 创建或删除表:如果流式传输到不存在的表,则会返回
notFound响应的变体。创建的表可能不会立即被后续的流式插入内容识别。同样,删除或重新创建表可能会导致在一段时间内,流式插入操作会传递到旧表。新表中可能不包含流式插入。 - 表截断:截断表的数据(通过使用
writeDisposition值为WRITE_TRUNCATE的查询作业)同样可能会导致在一致性周期内进行的后续插入操作被舍弃。
数据缺失或不可用
流式插入临时驻留在写入优化存储空间中,该存储空间具有不同于代管式存储空间的可用性特征。BigQuery 中的某些操作不与写入优化存储空间交互,例如表复制作业和 tabledata.list 等 API 方法。最近流式插入的数据不会出现在目标表或输出中。
流式插入配额错误
本部分提供了一些提示,可帮助您排查与将数据流式插入到 BigQuery 相关的配额错误。
在某些区域中,如果您不为每一行填写 insertId 字段,则流式插入将具有更高的配额。如需详细了解流式插入的配额,请参阅流式插入。BigQuery 流式传输的配额相关错误取决于是否存在 insertId。
错误消息
如果 insertId 字段为空,则可能会出现以下配额错误:
| 配额限制 | 出错提示 |
|---|---|
| 每个项目每秒字节数 | REGION 区域内项目 PROJECT_ID 中 gaia_id 为 GAIA_ID 的实体已超出每秒插入字节数的配额。 |
如果填写了 insertId 字段,则可能会出现以下配额错误:
| 配额限制 | 出错提示 |
|---|---|
| 每个项目每秒的行数 | REGION 中的项目 PROJECT_ID 已超出每秒流式插入行数的配额。 |
| 每个表每秒的行数 | 表 TABLE_ID 已超出每秒流式插入行数的配额。 |
| 每个表每秒字节数 | 表 TABLE_ID 已超出每秒流式插入字节数的配额。 |
insertId 字段的用途是删除重复的插入行。如果具有相同 insertId 的多个插入内容均在几分钟之内发送至 BigQuery,则 BigQuery 将写入单个版本的记录。但是,我们无法保证系统会自动删除重复的数据。为了最大限度的提高流式数据处理效率,我们建议您不要添加 insertId,而是使用手动去重。如需了解详情,请参阅确保数据一致性。
诊断
使用 STREAMING_TIMELINE_BY_* 视图分析流式流量。这些视图会每隔一分钟汇总流式统计信息(按 error_code 分组)。配额错误显示在结果中,其 error_code 等于 RATE_LIMIT_EXCEEDED 或 QUOTA_EXCEEDED。
根据达到的特定配额限制,请查看 total_rows 或 total_input_bytes。如果错误是表级配额,请按 table_id 进行过滤。
例如,以下查询显示每分钟注入的总字节数,以及配额错误总数:
SELECT start_timestamp, error_code, SUM(total_input_bytes) as sum_input_bytes, SUM(IF(error_code IN ('QUOTA_EXCEEDED', 'RATE_LIMIT_EXCEEDED'), total_requests, 0)) AS quota_error FROM `region-REGION_NAME`.INFORMATION_SCHEMA.STREAMING_TIMELINE_BY_PROJECT WHERE start_timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP, INTERVAL 1 DAY) GROUP BY start_timestamp, error_code ORDER BY 1 DESC
解决方法
要解决此配额错误,请执行以下操作:
如果您使用
insertId字段进行重复信息删除,并且您的项目位于支持较高流式配额的区域中,我们建议您移除insertId字段。此解决方案可能需要执行一些额外的步骤来手动移除重复数据。如需了解详情,请参阅手动移除重复数据。如果您未使用
insertId,或者不能将其移除,请监控 24 小时时间段的流式流量并分析配额错误:如果您看到的大多数是
RATE_LIMIT_EXCEEDED错误而不是QUOTA_EXCEEDED错误,而您的总流量低于配额的 80%,则这些错误可能指示暂时达到峰值。您可以通过在两次重试之间使用指数退避算法来重试操作,以消除这些错误。如果您使用 Dataflow 作业插入数据,请考虑使用加载作业,而非流式插入。如需了解详情,请参阅设置插入方法。如果您将 Dataflow 与自定义 I/O 连接器搭配使用,请考虑改为使用内置 I/O 连接器。如需了解详情,请参阅自定义 I/O 模式。
如果您看到
QUOTA_EXCEEDED错误或总体流量持续超过配额的 80%,请提交增加配额的申请。如需了解详情,请参阅申请配额调整。您可能还希望考虑将流式插入替换为新的 Storage Write API,该 API 具有更高的吞吐量、更低的价格和许多实用功能。