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调用
- 创建三个推送队列:
,小任务
,中任务
大任务
- 为每个请求设置最大并发请求数,使总数为最大并发API调用数(例如,如果最大并发API调用数为200,我可以将
设置为tasks small
为30,max\u concurrent\u requests
60和tasks medium
100)tasks large
- 在将任务排队时,检查每个队列中的挂起任务数(使用类似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所描述的:
- 我有好几张票