php - 使用公平槽策略从队列中获取下一个任务
问题描述
在我们的服务中,用户可以添加不同的任务,这些任务会在插槽可用时立即执行。
所有任务都存储在一个 mysql 表中。桌子看起来像
user_id | task | status | created_at | started_at
int | string | pending,active | datetime | datetime
我们目前正在使用先进先出策略,但由于任务数量正在增加,并且我们不想限制用户可以添加多少任务,我们希望为其添加公平槽策略。通常,任务在完成前运行 30 到 75 分钟。它也可以更少或更多。
我创建了一组示例数据:
示例数据:
158 total tasks
144 pending tasks
14 running tasks
15 tasks can run at the same time
# of pending tasks for each user
user 1 => 28 tasks
user 2 => 76 tasks
user 3 => 5 tasks
user 4 => 22 tasks
user 5 => 3 tasks
# of active tasks for each user
user 1 => 5 tasks
user 2 => 0 tasks
user 3 => 2 tasks
user 4 => 4 tasks
user 5 => 3 tasks
我的方法是
-first:将每个用户的待处理任务数除以待处理任务总数(pending_tasks_of_user_x / pending_tasks)。
-second:然后将活动任务划分为可以同时运行的任务数量(active_tasks_of_user_x / concurrent_tasks)。
但现在我不知道如何进行。如果我的方法完全错误,我愿意接受。
要访问数据库,我正在使用 php。
编辑:
公平地说,我定义用户不必等待,直到其他用户的所有其他任务完成。例如,用户 2 有 76 个任务,用户 1 有 28 个任务。现在用户 5 添加了 3 个任务。我不希望用户 5 必须等到必须先执行用户 1 和 2 的所有任务才能执行用户 5 的任务。更像是用户 2 可以同时运行 8 个任务,用户 1 4 和用户 5 可以运行 2,或者类似的东西。如果可用的用户多于并发任务,则它应该相应地缩小,并且一些必须等待。
解决方案
我认为 公平共享调度在这种情况下是一个很好的方法。
将可用任务槽的总数除以具有待处理任务的用户总数。
15 / 5 = 3
所以每个用户现在可以一次运行 3 个任务。
这意味着任务少的用户会很快完成,而任务多的用户则需要等待更长的时间。
如果另一个用户出现,可用的任务将是
15 / 6 = 2.5
当然你不能运行一半的任务,但这可以在实际的排队算法中解决。
我认为您可以在 PHP 中实现这一点。我不认为这是我为你编写代码的地方。
算法应该是这样的:
- 任务槽是免费的,正在寻找要执行的新任务。
- 找到运行任务最少的用户。
- 查找该用户最早的待处理任务。
- 如果用户没有任何待处理的任务,请从考虑中删除该用户并从第 2 点重新开始。
- 运行挂起的任务。
这就是实现这一点所需要做的一切。
推荐阅读
- regular-language - 证明以下语言是正则的:
- mysql - MySql 表和视图表的双重连接
- chronicle - 硬重置时文件损坏或截断
- angular-dart - 如何测试嵌套路由器?(旧:如何测试'
- node.js - 节点承诺循环返回承诺不起作用
- internet-explorer - 如何通过 Create React App 3.0 支持 IE 11?
- angular - 如何动态传递组件实例?
- java - OpenJDK 11 无法解析 javax.xml.* 属性
- javascript - 如何在代码之间使用 ActivityIndicator?
- java - 在 setter 方法中验证模型类