Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google app engine 在使用google app engine上的任务队列时,如何确定任务的优先级?_Google App Engine_Task Queue - Fatal编程技术网

Google app engine 在使用google app engine上的任务队列时,如何确定任务的优先级?

Google app engine 在使用google app engine上的任务队列时,如何确定任务的优先级?,google-app-engine,task-queue,Google App Engine,Task Queue,我试图解决以下问题: 我有一系列我想执行的“任务” 我有固定数量的worker来执行这些worker(因为它们使用urlfetch调用外部API,并且对该API的并行调用数量是有限的) 我希望“尽快”执行这些“任务”(即最小延迟) 这些任务是大型任务的一部分,可以根据原始任务的大小进行分类(即,小型原始任务可能会生成1到100个任务,中型任务可能会生成100到1000个任务,大型任务可能会生成1000个以上的任务) 棘手的部分:我想有效地完成这一切(即,尽量减少延迟并使用尽可能多的并行API调用

我试图解决以下问题:

  • 我有一系列我想执行的“任务”
  • 我有固定数量的worker来执行这些worker(因为它们使用urlfetch调用外部API,并且对该API的并行调用数量是有限的)
  • 我希望“尽快”执行这些“任务”(即最小延迟)
  • 这些任务是大型任务的一部分,可以根据原始任务的大小进行分类(即,小型原始任务可能会生成1到100个任务,中型任务可能会生成100到1000个任务,大型任务可能会生成1000个以上的任务)
  • 棘手的部分:我想有效地完成这一切(即,尽量减少延迟并使用尽可能多的并行API调用-而不超过限制),但同时尝试阻止从“大”原始任务生成大量任务来延迟从“小”原始任务生成的任务

    换句话说:我希望每个任务都有一个“优先级”,而“小”任务的优先级更高,从而防止“大”任务导致饥饿

    一些搜索似乎并不表明任何预先制作的东西都是可用的,因此我得出以下结论:

    • 创建三个推送队列:
      小任务
      中任务
      大任务
    • 为每个请求设置最大并发请求数,使总数为最大并发API调用数(例如,如果最大并发API调用数为200,我可以将
      tasks small
      设置为
      max\u concurrent\u requests
      为30,
      tasks medium
      60和
      tasks large
      100)
    • 在将任务排队时,检查每个队列中的挂起任务数(使用类似QueueStatistics类的方法),如果其他队列未100%使用,则将任务排队,否则仅将任务排队到相应大小的队列中
    例如,如果我们有任务
    T1
    ,它是小任务的一部分,首先检查
    tasks small
    是否有空闲的“插槽”,并将其排队。否则,请选中
    tasks medium
    tasks large
    。如果没有空闲的插槽,则将其放入
    小任务
    队列,并在处理之前在添加的任务之后对其进行处理(注意:这不是最佳的,因为如果“插槽”在其他队列上空闲,它们仍然不会处理
    小任务
    队列中的挂起任务)

    另一种选择是使用PULL队列,并让一个中央“协调器”根据优先级从该队列中拉出并分派它们,然而这似乎增加了一点延迟

    然而,这似乎有点老套,我想知道是否有更好的替代方案


    编辑:经过一些思考和反馈后,我想用以下方式使用PULL queue:

    • 有两个拉动队列(
      中等任务
      大任务
    • 具有并发性为1的调度程序(推送)队列(以便在任何时间只运行一个调度任务)。调度任务以多种方式创建:
      • 通过每分钟一次的cron作业
      • 将中/大型任务添加到推送队列后
      • 工人任务完成后
    • 具有并发性等于工作进程数的工作进程(推送)队列
    以及工作流程:

    • 小任务直接添加到工作队列中
    • 无论何时触发dispatcher任务,它都会执行以下操作:
      • 估计空闲工作线程的数量(通过查看工作线程队列中正在运行的任务的数量)
      • 对于任何“空闲”插槽,它将从中/大型任务拉队列中获取一个任务,并将其排入工作线程(或者更准确地说:将其添加到工作线程推队列,最终将在工作线程上执行)

    一旦实现并至少经过适度测试,我将向您报告。

    小型/中型/大型原始任务队列本身不会有多大帮助-一旦原始任务进入队列,它们将继续生成辅助任务,甚至可能会突破辅助任务队列大小限制。因此,您需要调整/控制原始任务的分配


    我将跟踪数据存储/GCS中的“todo”原始任务,并且仅当相应的队列大小足够小时(1个或2个挂起的作业)才将这些原始任务排队,无论是周期性任务、cron作业还是延迟任务(取决于您需要执行原始任务排队的速率)这将实现所需的速度和优先级逻辑,就像推队列调度器一样,但没有您提到的额外延迟。

    我没有使用拉队列,但据我所知,它们非常适合您的用例。您可以定义3个pull队列,并让
    X
    工作人员从中提取所有任务,首先尝试“小”队列,如果队列为空,则转到“中”(其中
    X
    是您的最大并发性)。您不需要中央调度器

    但是,即使没有任务(或
    X/threadsPerMachine
    ?),您也要为
    X
    工人支付费用,或者自己缩小规模


    因此,这里有另一个想法:创建一个具有正确的
    最大并发性的推送队列。当您收到新任务时,将其信息推送到数据存储,并将通用作业排队。然后,该通用作业将查询数据存储,按优先级顺序查找任务,并执行它找到的第一个任务。这样,下一个作业仍将执行一个短任务,即使该作业已从一个大任务排队。

    编辑:我现在迁移到一个更简单的解决方案,类似于@eric simonton所描述的:

    • 我有好几张票