BigQuery Python客户端-超时参数的含义以及如何设置查询结果超时

问题描述

此问题与BigQuery Python客户端中QueryJob对象的timeout方法中的result参数有关。

相对于版本1.24.0,看来timeout的含义已更改。

例如,documentation for QueryJob's result in version 1.24.0指出超时为:

使用重试之前等待基础HTTP传输的秒数。如果在后台进行了多个请求,则超时将解释为所有请求的大约总时间。

据我了解,这可以用作限制result方法调用等待结果的总时间的一种方法

例如,考虑以下脚本:

import logging

from google.cloud import bigquery

# Set logging level to DEBUG in order to see the HTTP requests
# being made by urllib3
logging.basicConfig(level=logging.DEBUG)

PROJECT_ID = "project_id" # replace by actual project ID

client = bigquery.Client(project=PROJECT_ID)

QUERY = ('SELECT name FROM `bigquery-public-data.usa_names.usa_1910_2013` '
        'WHERE state = "TX" '
        'LIMIT 100')
TIMEOUT = 30  # in seconds
query_job = client.query(QUERY)  # API request - starts the query
assert query_job.state == 'RUNNING'

# Waits for the query to finish
iterator = query_job.result(timeout=TIMEOUT)
rows = list(iterator)

assert query_job.state == 'DONE'

据我了解,如果获取结果涉及的所有API调用加起来超过30秒,则对result调用将放弃。因此,timeout在这里用来限制result方法调用的总执行时间。

但是,更高版本引入了更改。例如,documentation for result in 1.27.2指出超时为:

使用重试之前等待基础HTTP传输的秒数。如果在后台多次提出请求,则超时适用于每个单独的请求。

如果我正确理解这一点,那么上面的示例将完全改变含义,并且对result调用可能会花费30秒钟以上的时间。

我的疑问是:

  1. 如果我使用新版本的result与旧版本运行,上面的脚本到底有什么区别?
  2. 当前推荐的将timeout值传递给result的用例是什么?
  3. 在等待查询结果后,给定的总时间后,当前建议的超时方法是什么?

谢谢。

解决方法

正如您在此fix中所看到的:

使传输层超时独立于查询超时, 即等待查询完成的最长时间。

查询超时由阻塞轮询使用,因此后端 轮询作业完成时不会阻塞太长时间,但是 运输可能有不同的超时要求,我们不希望 有时会引起不必要的超时错误。

  • 将超时应用于每个基础请求

由于作业方法不再在所有请求之间分配超时,因此 方法可能会使客户端方法以相同的方式进行调整。

因此,基本区别在于,在以前的版本中,如果在下面的层中进行了许多请求,则它们将共享30秒的超时时间。换句话说,如果第一个请求花费20秒,第二个请求将在10秒后超时。 在新版本中,每个请求都将有30秒的时间。

关于用例,基本上取决于您的应用程序。如果您不能长时间等待可能丢失的请求,则可以减少超时。