Google app engine 使用应用程序引擎标准中的BigQuery的最佳实践是什么?
我使用的是AppEngine标准环境(autoscaled),这意味着在取消请求之前,我有10分钟的时间限制 目标是定期从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
// 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完成以提供示例,您可以稍后使用以下命令翻译为任何语言):
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
您可以在中尝试此操作。不幸的是,无法从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