排查 BigQuery Storage API 错误

本文档介绍了在使用 BigQuery Storage Read API、BigQuery Storage Write API (gRPC) 或通过 BigQuery Storage Write API (REST)(tabledata.insertAll 方法)进行流式插入时,如何排查 BigQuery 中的数据读取或流式传输问题。

使用 INFORMATION_SCHEMA 视图分析流式遥测数据

您可以查询 INFORMATION_SCHEMA 视图,以监控流式注入的健康状况、发现吞吐量瓶颈,并检查一分钟间隔内的错误代码:

以下示例查询 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 小时超时时间时,就会发生此错误。

解决方法:

  1. 提高作业的并行度。
  2. 如果工作器节点的 CPU 利用率相对稳定且不超过 85%,请考虑在更大的机器类型上运行作业。
  3. 将作业拆分为多个作业或更小的查询。

如需详细了解会话管理和数据读取,请参阅 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 具有更高的吞吐量、更低的价格和许多实用功能。