php - Laravel - 如何将作业从一个redis队列移动到另一个redis队列?
问题描述
例如,我有两个队列“高”和“低”。我在“高”队列中有 1000 个工作,在“低”队列中有 0 个工作。现在我想将例如 500 个作业从“高”队列移动到“低”队列。
首先,最好了解如何转移所有工作,而不仅仅是其中一半。
我可以使用此命令获得所有工作:
\Redis::lrange('queues:' . $name, 0, -1);
但是如何移动它们,知道吗?
解决方案
总结评论中的讨论,这里有一些建议和附加信息。
手动调整 Redis 队列
不建议手动干预redis队列。不要手动更改队列。相反,让队列工作人员处理具有意外(高)工作负载的队列。您还可以临时生成额外的队列工作人员以更快地完成工作。
不过,在处理未来的功能时,可能会考虑到不平衡的队列负载。
修复队列工作负载
要解决队列工作负载,有多种解决方案。它们的共同点是我们在各个队列之间共享资源。唯一的区别是实现这一点的方式。
对于以下选项,我将使用一个非常基本的示例。想象一个简单的云应用程序,用户可以在其中购买一些计算能力(无论如何)。为了让事情更有趣,应用程序的用户还可以购买优先队列票,这保证了他们的优先处理。换句话说,他们的请求应该(但不是必须)优先处理。
1.重新调整队列工作进程
共享资源的一种方法是根据工作负载放大和缩小队列工作进程。这意味着我们减少了一个队列的队列工作进程,以便为另一个队列提供额外的队列工作人员的资源。
在我们的示例中,我们可能希望我们的用户使用 10 次中的 9 次非优先处理,因为他们不想为更快的处理支付额外费用。low
这意味着对于优先级队列中的 1 个工作项,我们通常在优先级队列中有 9 个工作项high
。为了使优先级处理有意义,我们现在需要每个队列 3 个队列工作进程。我们将像这样启动流程:
- 3x
php artisan queue:work --queue=high
- 3x
php artisan queue:work --queue=low
如果现在高优先级队列突然有更多的工作项(例如,由于优先队列票的销售),我们需要相应地重新调整我们的队列工作人员。为此,我们必须手动终止一些--queue=low
工作进程并启动更多工作进程--queue=high
。
因为手工操作非常麻烦(而且我们的开发人员也需要偶尔睡觉),所以有一个解决方案,称为Laravel Horizon。当正确配置balance
模式设置为 时auto
,Horizon 将确保具有较高工作负载的队列确实比具有较少工作负载的队列得到更多关注。换句话说,Horizon 将尝试在队列之间实现相等的等待时间。
2.让队列工作者在多个队列上工作
一种不太复杂的方法是让队列工作人员在多个队列上进行侦听和工作。这可以通过将多个逗号分隔的队列传递给--queue
参数来完成:--queue=high,low
这样做时,我们指示队列工作程序处理队列上high
的工作项,其优先级高于队列上的工作项low
。high
这意味着工作人员在从队列中获取工作之前总是会完全清除low
队列。如果在处理low
队列中的作业后,worker 发现队列中的项目high
,他将跳回该队列。所以每次worker寻找一个新的工作项,他会先在high
队列中查找,如果没有工作项,他会去low
队列。
对于上面的示例,我们可以部署以下 6 个队列工作器:
- 4x
php artisan queue:work --queue=high,low
- 2x
php artisan queue:work --queue=low
在这种情况下,我们将(按比例)为high
队列拥有比队列更多的工作资源low
。low
但是当他们没有任何优先工作要做时,这些资源会帮助队列中的其他工作。
我们当然也可以将high
队列作为后备添加到我们的low
队列工作者中:
- 4x
php artisan queue:work --queue=high,low
- 2x
php artisan queue:work --queue=low,high
通过这种方式,他们将能够high
在上述销售情况下工作超载的情况下帮助我们的优先队列工作人员。
结论
简单的解决方案通常更好。当您的工作量没有突然爆发并且您可以很好地预测它们时,请使用第二种方法(但要使用主管,这样您就不必一直手动启动工人,也可以使确保它们在发生崩溃时重新启动)。
另一方面,如果您的工作量变化很大,并且您无法真正提前知道您需要多少队列工作人员,那么 Horizon 可能值得一看。就个人而言,我也将 Horizon 用于相当简单的项目,因为它很容易设置,而且它可以让我省去我必须考虑很多负载和东西的工作。
推荐阅读
- python - 如何使用 jupyter notebook 在 pandas 数据框中列出列表
- html - 如何在浏览窗口中获取选定的文件路径?
- sql - 根据另一个表过滤具有无效字段值的数据
- sql - SQL Server 如何判断输入日期的格式?
- c - C 中带有 TI 编译器的 struct 中的可变长度数组(套接字编程)
- c# - 如何在单独的类库中管理客户端上下文对象?
- jenkins - 如何在 Jenkins 中手动安装 Black Duck Detect
- python - 如何部署 rasa 聊天机器人
- esb - Tibco ActiveMatrix ESB Iso-8583 连接器
- javascript - 重新定位/自定义图表和表格需要放置在仪表板中的位置 - Google 脚本