我正在尝试安排PySpark工作。我遵循GCP文档并最终向App Engine部署了一个小python脚本,它执行以下操作:
问题是,我需要群集启动并运行,否则不会发送作业(呃!)但我不希望群集始终启动并运行,特别是因为我的工作需要运行一个月一次。
我想在我的python脚本中添加集群的创建,但调用是异步的(它发出HTTP请求),因此我的作业是在集群创建调用之后但在集群真正启动并运行之前提交的。 / p>
我该怎么办?
我想要的东西更干净,而不仅仅是在我的剧本中等待几分钟!
由于
编辑:这是我的代码到目前为止的样子:
启动工作
class EnqueueTaskHandler(webapp2.RequestHandler):
def get(self):
task = taskqueue.add(
url='/run',
target='worker')
self.response.write(
'Task {} enqueued, ETA {}.'.format(task.name, task.eta))
app = webapp2.WSGIApplication([('/launch', EnqueueTaskHandler)], debug=True)
工作
class CronEventHandler(webapp2.RequestHandler):
def create_cluster(self, dataproc, project, zone, region, cluster_name):
zone_uri = 'https://www.googleapis.com/compute/v1/projects/{}/zones/{}'.format(project, zone)
cluster_data = {...}
dataproc.projects().regions().clusters().create(
projectId=project,
region=region,
body=cluster_data).execute()
def wait_for_cluster(self, dataproc, project, region, clustername):
print('Waiting for cluster to run...')
while True:
result = dataproc.projects().regions().clusters().get(
projectId=project,
region=region,
clusterName=clustername).execute()
# Handle exceptions
if result['status']['state'] != 'RUNNING':
time.sleep(60)
else:
return result
def wait_for_job(self, dataproc, project, region, job_id):
print('Waiting for job to finish...')
while True:
result = dataproc.projects().regions().jobs().get(
projectId=project,
region=region,
jobId=job_id).execute()
# Handle exceptions
print(result['status']['state'])
if result['status']['state'] == 'ERROR' or result['status']['state'] == 'DONE':
return result
else:
time.sleep(60)
def submit_job(self, dataproc, project, region, clusterName):
job = {...}
result = dataproc.projects().regions().jobs().submit(projectId=project,region=region,body=job).execute()
return result['reference']['jobId']
def post(self):
dataproc = googleapiclient.discovery.build('dataproc', 'v1')
project = '...'
region = "..."
zone = "..."
clusterName = '...'
self.create_cluster(dataproc, project, zone, region, clusterName)
self.wait_for_cluster(dataproc, project, region, clusterName)
job_id = self.submit_job(dataproc,project,region,clusterName)
self.wait_for_job(dataproc,project,region,job_id)
dataproc.projects().regions().clusters().delete(projectId=project, region=region, clusterName=clusterName).execute()
self.response.write("JOB SENT")
app = webapp2.WSGIApplication([('/run', CronEventHandler)], debug=True)
一切正常,直到删除群集。此时我收到“DeadlineExceededError:超出了响应HTTP请求的总体截止日期。”任何的想法 ?
答案 0 :(得分:3)
除了通过群集上的list
或get
请求或使用CreateCluster请求返回的操作进行常规轮询之外,对于这样的一次性群集,您还可以考虑使用{{3如果你不想使用成熟的工作流程模板,可能还有Dataproc Workflows API;在此API中,您使用单个请求指定群集设置以及要提交的作业,并且只要群集准备好,就会自动运行作业,之后将自动删除群集。
答案 1 :(得分:0)
您可以使用Google Cloud Dataproc API至create
,delete
和list
群集。
list
操作可以在create
和delete
操作后(重复)执行,以确认它们已成功完成,因为它提供了ClusterStatus
个群集中的UNKNOWN The cluster state is unknown.
CREATING The cluster is being created and set up. It is not ready for use.
RUNNING The cluster is currently running and healthy. It is ready for use.
ERROR The cluster encountered an error. It is not ready for use.
DELETING The cluster is being deleted. It cannot be used.
UPDATING The cluster is being updated. It continues to accept and process jobs.
相关State
信息的结果:
list
为了防止(重复的)list
调用之间的平等等待(通常不是GAE上的好事),您可以将push task queue(带有相关的上下文信息)允许的延迟任务排队您可以在以后执行此类datetime.datetime
操作。例如,在python中,请参阅taskqueue.add()
:
倒计时 - 此任务应运行或租用的未来秒数。默认为零。如果,请不要指定此参数 你指定了一个eta。
eta - 一个{{1}},指定任务运行的绝对最早时间。如果,则无法指定此参数 指定了倒计时参数。这个论点可以是时间 区域感知或时区天真,或设置为过去的时间。如果 参数设置为None,默认值为now。对于拉动任务,没有 工人可以在eta指示的时间之前租用任务 参数。
如果在任务执行时,结果表明感兴趣的操作仍在进行中,则只需将另一个这样的延迟任务排入队列 - 有效地轮询但没有实际的等待/休眠。