Google app engine 使用应用程序引擎标准中的BigQuery的最佳实践是什么?

Google app engine 使用应用程序引擎标准中的BigQuery的最佳实践是什么?,google-app-engine,google-bigquery,Google App Engine,Google Bigquery,我使用的是AppEngine标准环境(autoscaled),这意味着在取消请求之前,我有10分钟的时间限制 目标是定期从BigQuery查询数据,并为每个记录在任务队列中创建一个任务,以便可以在后台处理记录 在状态下等待以下作业的说明: // Create a job ID so that we can safely retry. JobId jobId = JobId.of(UUID.randomUUID().toString()); Job queryJob = bigquery.crea

我使用的是AppEngine标准环境(autoscaled),这意味着在取消请求之前,我有10分钟的时间限制

目标是定期从BigQuery查询数据,并为每个记录在任务队列中创建一个任务,以便可以在后台处理记录

在状态下等待以下作业的说明:

// Create a job ID so that we can safely retry.
JobId jobId = JobId.of(UUID.randomUUID().toString());
Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());

// Wait for the query to complete.
queryJob = queryJob.waitFor();
问题是10分钟的限制,因为BigQuery查询是在后台处理的,可能需要一段时间才能得到结果,所以我可能无法在同一个端点调用中处理响应

  • 当查询准备就绪时,是否有方法在URL处接收来自BigQuery的回调
  • 在应用程序引擎标准中是否有更智能的方法来处理来自BigQuery的数据

我知道我可以配置App Engine以延长每个请求的最大时间,但这很难是解决方案。

一种可行的方法是在应用程序代码中处理作业生命周期管理,而不是依赖自动为您执行此操作的包装器(在作业完成之前,包装器会一直阻塞)

发件人:

要以编程方式运行作业,请执行以下操作:

  • 通过调用
    作业启动作业。使用唯一的。服务器生成一个作业
    如果省略它,则为您提供ID,但生成
    客户端上的作业ID,以允许可靠重试
    作业。插入
    
    打电话

    调用
    jobs.insert
    方法时,请包含作业资源 包含指定作业类型的子属性的表示 -或

  • 通过调用
    jobs检查作业状态。使用作业ID获取
    ,并检查值以了解作业状态。什么时候
    状态。状态
    完成
    ,作业已停止运行;但是,
    DONE
    状态并不意味着作业已成功完成,只是 它不再运行

    注意:有一些包装函数用于管理作业状态 对你的要求。例如,运行
    jobs.query
    会创建一个作业并 在指定的时间段内定期轮询
    DONE
    状态

  • 检查工作是否成功。如果作业具有属性,则作业失败。
    status.errorResult
    属性保持不变 描述失败作业中出现问题的信息。如果
    状态。errorResult
    不存在,作业成功完成, 虽然可能存在一些非致命错误,例如问题 在加载作业中导入几行。在中返回非致命错误 作业的
    状态。错误
    列表

  • 基本上,您可以启动后台作业,然后重复调用以查询作业的状态(例如,在延迟的推送队列任务中),而不是使用单个阻塞调用来等待作业完成(
    queryJob.waitFor();
    )当它完成时,你实际上开始处理结果

    和可能也会引起兴趣


    注意:答案完全基于文档,我还不是BigQuery用户。

    最好的选择是像BQ那样处理长时间运行的任务:提供作业id并允许客户查询它,在查询尚未完成时返回一段时间,并在结果准备好供客户使用时返回200

    此外,202可以返回一个主体,因此您可以为客户端设置不同的状态(例如,“排队”、“运行”、“处理结果”…)

    在服务器端,您启动一个查询,只要BQ返回一个作业ID,就将其存储在某个持久性存储中(我会选择,但也可以是实例,甚至是中的文件)

    然后,您只需要创建一个用于检查BQ的未完成查询的状态,并相应地更新其在持久存储中的状态。BQ作业完成后,您可以检索结果并存储它们,以便在客户机检查您的服务时准备好

    例如,这是您应该在应用程序中执行的BQ API查询(在这里使用curl完成以提供示例,您可以稍后使用以下命令翻译为任何语言):

  • 创建作业,从响应中检索作业id,并将其存储:

    PROJECT=$(gcloud config get-value project)
    QUERY='SELECT * FROM `bigquery-samples.wikipedia_benchmark.Wiki1k` limit 0'
    curl -H"Authorization: Bearer $(gcloud auth print-access-token)" -H'content-type:application/json' https://www.googleapis.com/bigquery/v2/projects/$PROJECT/jobs -d"
    {
     \"configuration\": {
      \"query\": {
       \"query\": \"$QUERY\",
       \"useLegacySql\": false
      }
     },
     \"jobReference\": {
      \"projectId\": \"$PROJECT\"
     }
    }"|jq -r .jobReference.jobId >> running_jobs
    
  • 继续查询作业状态的BQAPI。(这可能是您的cron工作):


  • 您可以在中尝试此操作。

    不幸的是,无法从BigQuery获得回电。您将如何处理查询/作业的结果?i、 e.您能否再解释一下为什么需要等待作业完成。@GrahamPolley我们的服务器将使用情况数据流式传输到BigQuery(与电话通话分钟数相比),然后使用查询(例如,按参与者)合并数据。我计划在任务队列中为每个这样的合并记录创建一个任务,以便进一步处理它。这与谷歌的应用引擎计费系统非常相似,在该系统中,数据从服务器收集、整合,然后在大约5分钟的时间间隔内决定给定资源是否可用。因此,本质上,您需要安排一些BigQuery作业/查询来处理一些数据,并将结果写入新表。是吗?是的,这是正确的,到目前为止,这也是可行的(我对聚合和重复数据消除进行了编码)。问题是数据需要在AppEngine标准环境中进一步处理。我想从表中提取数据并将记录标记为已提取不是一个好的选择。我错过了一个钩子或者每次创建记录时调用URL的东西,所以应用程序引擎可以一个记录一个记录地进一步处理数据。不太清楚10分钟的限制是什么意思。GAE请求处理程序必须返回响应,否则将返回500。另一方面,有10分钟(如果选择手动自动校准)或最多24小时
    for job in $(cat running_jobs); do
      if [ $(curl -H"Authorization: Bearer $(gcloud auth print-access-token)" https://www.googleapis.com/bigquery/v2/projects/$PROJECT/jobs/$job|jq -r .status.state) = "DONE" ]; then
        # here your processing part including your callback
        # then remove the job from the list of running jobs
        sed -i "/$job/d" ./running_jobs
      fi
    done