我试图解决以下问题:
棘手的部分:我希望有效地完成所有这些工作(即最小延迟并尽可能多地使用并行API调用 - 不超过限制),但同时尝试阻止大量任务由" large"生成延迟从"小"生成的任务的原始任务原始任务。
换句话说:我希望有一个"优先级"用" small"分配给每个任务。具有更高优先级的任务,从而防止“大”"任务。
有些搜索似乎没有表明预制的任何内容都可用,所以我想出了以下内容:
tasks-small
,tasks-medium
,tasks-large
tasks-small
* max_concurrent_requests
为30,tasks-medium
60和tasks-large
100)例如,如果我们将任务T1
作为小任务的一部分,请首先检查tasks-small
是否有空闲"插槽"并将它排列在那里。否则请检查tasks-medium
和tasks-large
。如果它们都没有空闲插槽,那么无论如何都会将它排入tasks-small
并在处理之前添加任务后处理它(注意:这不是最佳的,因为如果"插槽"释放在其他队列中,他们仍然无法处理来自tasks-small
队列的待处理任务)
另一种选择是使用PULL队列并拥有一个中央协调员"根据优先级从该队列中拉出并调度它们,但这似乎会增加一点延迟。
然而,这似乎有点hackish,我想知道是否有更好的选择。
编辑:经过一些思考和反馈后,我想以下列方式考虑使用PULL队列:
medium-tasks
和large-tasks
)工作流程:
一旦实施并且至少经过适度测试,我会向您报告。
答案 0 :(得分:1)
小/中/大原始任务队列本身无济于事 - 一旦原始任务入队,它们将继续产生工作任务,甚至可能破坏工作人员任务队列大小限制。因此,您需要调整/控制原始任务的排队。
我会跟踪数据存储区/ GCS中的“todo”原始任务,并且仅当相应的队列大小足够低(1个或可能是2个待处理作业)时才将这些原始任务排入,来自重复任务,cron作业或延迟任务(取决于您需要执行原始任务排队的速率),它将像推送队列调度程序一样实现所需的调步和优先级逻辑,但没有额外的延迟你提到过。
答案 1 :(得分:1)
我没有使用过拉队列,但根据我的理解,它们可以很好地适合你的用例。你可以定义3个拉队列,并让X
个工作人员从他们那里拉出任务,首先尝试"小"排队然后继续前进到#34; medium"如果它是空的(其中X
是你的最大并发)。你不应该需要一个中央调度员。
然而,即使没有任务(或X
?),您也可以为X / threadsPerMachine
工作人员付费,或者将其缩小&你自己。
所以,这是另一个想法:使用正确的maximum concurrency
制作单个推送队列。收到新任务后,将其信息推送到数据存储区,然后排队通用作业。然后,该通用作业将查询数据存储区,以优先级顺序查找任务,执行它找到的第一个任务。这样,即使该作业已经从大型任务中排队,下一个作业仍将执行短任务。
答案 2 :(得分:0)
最后一点是必要的 - 除其他原因外 - 因为PULL队列中的拉/秒数限制为10k / s:https://cloud.google.com/appengine/docs/python/taskqueue/overview-pull#Python_Leasing_tasks
我实现了UPDATE中描述的解决方案:
有关详细信息,请参阅问题。一些说明: