排查 BigQuery 配额错误

BigQuery 设有各种配额,用于限制传入请求的速率和数量。这些配额可搭配使用以保护后端系统,并在您提交非常大的作业时帮助防止意料之外的计费。本文档介绍了如何诊断和减少由配额导致的错误。

概览

如果 BigQuery 操作因配额限制而失败,API 会返回 HTTP 403 Forbidden 状态代码。响应正文会详细说明已达到的限制。响应正文类似于以下内容:

{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Quota exceeded: ...",
    "reason" : "quotaExceeded"
  } ],
  "message" : "Quota exceeded: ..."
}

载荷中的 message 字段会说明超出了哪个限制。例如,message 字段可能会显示 Exceeded rate limits: too many table update operations for this table

一般来说,配额限制分为两类,由响应载荷中的 reason 字段指示。

  • rateLimitExceeded。该值表示短期限制。通常,您可以在几秒钟后重试操作以解决这些限制。在两次重试尝试之间使用指数退避算法。也就是说,以指数方式增加每次重试之间的延迟时间。

  • quotaExceeded。该值表示长期限制。如果您达到了长期配额上限,则应等待 10 分钟或更长时间,然后再重试操作。如果您持续达到其中一个长期配额限制,则应分析您的工作负载以寻求缓解问题的方法。缓解措施可能包括优化工作负载或申请增加配额。

对于 quotaExceeded 错误,请检查错误消息以了解超出了哪个配额限制。然后分析您的工作负载,查看是否可以避免达到配额(例如通过优化查询性能)。在某些情况下,您可以通过与 BigQuery 支持团队联系与 Google Cloud 销售人员联系来增加配额。

您可以使用 INFORMATION_SCHEMA 视图分析潜在的问题。这组视图包含有关 BigQuery 资源的元数据,包括作业、预留和流式插入。例如,以下查询使用 JOBS_BY_PROJECT 视图列出过去一天中与配额相关的所有错误。

SELECT
 job_id,
 creation_time,
 error_result
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP, INTERVAL 1 DAY) AND
      error_result.reason IN ('rateLimitExceeded', 'quotaExceeded')

您还可以在 Cloud Audit Logs 中查看错误。例如,使用日志查看器,以下查询会找出消息字符串中包含 Quota exceeded 的错误:

resource.type = ("bigquery_project" OR "bigquery_dataset")
protoPayload.status.code ="7"
protoPayload.status.message: "Quota exceeded"

(状态代码 7PERMISSION_DENIED,对应于 HTTP 403 状态代码。)

流式插入配额错误

本部分提供了一些有关排查与将数据流式插入 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 等于 RATE_LIMIT_EXCEEDEDQUOTA_EXCEEDED

根据达到的特定配额限制,请查看 total_rowstotal_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-us`.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%,则这些错误可能指示暂时达到峰值。您可以通过在两次重试之间使用指数退避算法来重试操作,以处理这些错误。

  • 如果您看到 QUOTA_EXCEEDED 错误或总体流量持续超过配额的 80%,请提交增加配额的申请。