2

GoogleApp Engineを使用していますが、JSON APIを介してBigQueryにクエリを送信すると、誤った結果が返されることがあります。通常、BigQuery内の単一のテーブルに限定されます(作成されるバッチジョブごとに新しいテーブルを作成します)。本番環境でこの問題が発生した場合、送信したクエリをログに記録し、BigQueryダッシュボードを介して実行してみます。BigQueryダッシュボードは予想よりも長く実行されますが、予想される結果が返されます。

問題を示す応答には何もありません。jobCompleteとして戻ってきますが、、、、、だけが 表示されTrueません。rowsjobReferenceschematotalRows = 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上のusignBigQueryのほとんどの例では、共有httplib2オブジェクトを使用していますが、これは誤った使用法です。クレデンシャルストアのみがスレッドセーフであり、共有できます
  2. BigQueryのクエリには10秒のタイムアウトがあります。

共有httpオブジェクトとタスクキューを使用してBigQueryを並行して複数回呼び出していましたが、クエリが完了するまでに10秒以上かかりました。これが、応答が呼び出し間で混在し、結果が期待どおりにならない理由です。例-クエリリクエストに対する検出応答を受け取ることがありました

修正:

呼び出し間でhttplib2オブジェクトを共有しないように、BigQueryクライアントコードを書き直し、クエリを実行するためにBigQueryジョブを送信するプロセスと、query()呼び出しを使用するプロセスを切り離します。通話の管理、ステータスの確認、結果の受信にはさらに多くのオーバーヘッドがありますが、少なくとも今は機能しており、応答は理にかなっています。

于 2012-12-19T21:20:36.020 に答える