2

我正在使用 GoogleApp Engine,有时当我通过 JSON API 向 BigQuery 发送查询时,我会得到不正确的结果。它通常仅限于 BigQuery 中的一个表(我为每个创建的批处理作业创建一个新表)。当我在生产中遇到这个问题时,我会记录我提交的查询并尝试通过 BigQuery 仪表板运行它,该仪表板的运行时间比预期的要长,但会返回预期的结果。

响应中没有任何内容表明存在问题。jobComplete回来了,但True我看不到rows,只有jobReference, schematotalRows = 0

在这种情况下是否适合进行调用以获取作业结果,即使我应该期望当前调用返回结果?

相关代码:

http = httplib2.Http(memcache)
self.credentials = AppAssertionCredentials(scope='https://www.googleapis.com/auth/bigquery')
self.http = self.credentials.authorize(http=http)
self.service = build('bigquery','v2',http=self.http)
jobs = self.service.jobs()
result = jobs.query(projectId=settings.GOOGLE_APIS_PROJECT_ID,
                                body={'query': query}).execute()

回复:

{u'totalRows': u'0', u'kind': u'bigquery#queryResponse', u'jobComplete': True, u'jobReference': {u'projectId': u'<REMOVED>', u'jobId': u'<REMOVED>'}, u'schema': {u'fields': [<REMOVED>]}}

无论我尝试在生产中重新运行查询多少次,都会返回相同的结果(这可能是由于通过 memcache 完成的缓存将不正确的结果缓存为响应?)

4

1 回答 1

1

问题是以下几种情况的混合:

  1. 共享的 http 对象不是线程安全的!(https://developers.google.com/api-client-library/python/guide/thread_safety)。尽管 GAE 上使用 BigQuery 的大多数示例都使用共享的 httplib2 对象,但这是不正确的用法。只有凭证存储是线程安全的并且可以共享
  2. BigQuery 上的查询有 10 秒超时。

我正在使用共享的 http 对象和任务队列并行多次调用 BigQuery,并且查询需要 10 多秒才能完成。这就是为什么响应会在呼叫之间混合,结果不会像预期的那样。例如 - 我有时会收到对我的查询请求的发现响应

修复:

重新编写我的 BigQuery 客户端代码,以便在调用之间不共享 httplib2 对象,并将我的进程解耦以提交 BigQuery 作业以运行查询,而不是使用 query() 调用。在管理呼叫、检查状态和接收结果方面有更多的开销,但至少它现在可以工作并且响应是有意义的。

于 2012-12-19T21:20:36.020 回答