合并cron作业以减少实例数量

时间:2018-08-03 09:00:12

标签: google-app-engine

假设我有3个请求:

@app.route('/schedulejob1/')
def schedulejob1():
   for pram in prams1:
     deferred.defer(scheduletjob1Task,pram)
   return 'Running'
@app.route('/schedulejob1/')
def schedulejob1():
   for pram in prams2:
     deferred.defer(scheduletjob1Task,pram)
   return 'Running'
@app.route('/schedulejob1/')
def schedulejob1():
   for pram in prams3:
     deferred.defer(scheduletjob1Task,pram)
   return 'Running'

所以我的cron.yaml是

cron:
- description: Run schedule job1
  url: /schedulejob1/
  schedule: every 1 minutes
- description: Run schedule job2
  url: /schedulejob2/
  schedule: every 1 minutes
- description: Run schedule job3
  url: /schedulejob3/
  schedule: every 1 minutes

此方法每分钟将有3个请求,因此gae将有很大机会动态创建更多实例,从而增加了成本(实例x前端/后端小时)。

我的计划是将3个请求放入一个请求:

@app.route('/schedulejobs/')
def schedulejobs():
   for pram in prams1
     deferred.defer(scheduletjob1Task,pram)
   for pram in prams2  
     deferred.defer(scheduletjob2Task,pram)
   for pram in prams3 
     deferred.defer(scheduletjob3Task,pram)

然后

 cron:
    - description: Run schedule jobs
      url: /schedulejobs/

第二种方法是否有助于减少请求数量?因此降低成本?

我的目标是将请求分成多个任务队列,每个任务队列在不到1分钟的时间内运行,并且可能永久失败(或可以重试1次)。 我还将在后端实例上放置一半的cron作业,以利用9个小时的空闲时间。

如果您不知道如何减少实例时间,请提出建议。

1 个答案:

答案 0 :(得分:1)

是的,具有重复计划的cron作业可能会导致不必要的活动高峰,从而增加实例时间。在分钟开始时,不仅每分钟平均有3个请求,而且在应用程序的请求队列中同时有3个请求 。如果您使用自动/基本缩放配置,则GAE可能会决定生成其他实例以保持较低的请求延迟,即使单个实例可以轻松地平均每分钟处理3个请求。

侧面说明:您已经收到cron请求来触发作业,您有点不必要地创建了另一个(任务队列)请求以实际执行作业(因此,在您的情况下,每分钟6个请求),为什么不直接从cron处理程序中执行作业呢?

现在,如果每个请求需要大约1分钟才能完成交错,将无济于事-@MatrixTai的评论适用。

但是,如果所有3个作业的总执行时间少于1分钟,则错开它们将有助于降低成本。在这种情况下,也许更好的方法是不要再创建3个请求-缺点是您仍然需要仔细配置延迟以确保它们不重叠,而只是顺序执行3个作业,而不会使新请求排队(这就是我的工作):

@app.route('/per_minute_jobs/')
def handle_per_minute_jobs():  # OK if the combined execution time is < 1 min
     execute_job_1()
     execute_job_2()
     execute_job_3()

使用这种方法,您每分钟恰好有1个请求,就其本身而言,它不能像其他方法那样触发生成新实例。

现在,合并的作业执行可能比典型的(非cron)请求处理花费更长的时间。如果您在同一个GAE服务中同时处理这两个实例,那么即使您的应用总体上的平均流量很低,以至于显然仅用一个实例即可处理它们,您仍将至少运行两个实例

更新:

好吧,由于您必须将工作拆分为后续任务,因此只需使用deferred.defer()的可选countdowneta参数来使这些任务及时错开并平滑那些活动高峰