例如,我有两个队列“高”和“低”。 我在“高”队列中有1000个作业,在“低”队列中有0个作业。 现在,我想将500个作业从“高”队列移至“低”队列。
开始时,最好找出如何转移所有工作,而不仅仅是其中一半。
我可以使用以下命令获取所有作业:
\Redis::lrange('queues:' . $name, 0, -1);
但是,如何移动它们,知道吗?
答案 0 :(得分:1)
为了总结评论中的讨论,这里有一些建议和更多信息。
不建议手动干预redis队列。请勿手动更改队列。而是让队列工作者处理具有意外(高)工作负载的队列。您还可以临时生成其他队列工作器,以更快地完成工作。
不过,在将来使用功能时,也许会考虑不均衡的队列负载。
要解决队列工作负荷,有许多解决方案。他们的共同点是我们在各个队列之间共享资源。唯一的区别是实现方法。
对于以下选项,我将使用一个非常基本的示例。想象一下一个简单的云应用程序,用户可以在其中购买一些计算能力(不管用什么)。为了使事情变得更有趣,应用程序的用户还可以购买优先队列票证,以保证他们得到优先处理。换句话说,他们的请求应该(但不是必须)得到优先处理。
一种共享资源的方法是根据工作负载来扩大和缩小队列工作进程。这意味着我们减少了一个队列的队列工作进程,从而为另一队列拥有了其他队列工作程序的资源。
在我们的示例中,我们可能希望用户使用非优先级处理的10倍之9,因为他们不想为加速处理而支付额外的费用。这意味着我们通常在low
优先级队列中有9个工作项,而在high
优先级队列中有1个工作项。为了使优先级处理有意义,我们现在每个队列需要3个队列工作进程。我们将开始这样的过程:
php artisan queue:work --queue=high
php artisan queue:work --queue=low
如果现在高优先级队列突然有更多的工作项(例如,由于出售优先队列票证引起的),我们将需要相应地重新调整队列工作者的规模。为此,我们将不得不手动终止某些--queue=low
工作进程,并启动更多--queue=high
工作进程。
由于手动操作非常麻烦(我们开发人员也需要偶尔睡觉),因此有一种解决方案称为Laravel Horizon。将balance
模式正确配置为auto
后,Horizon将确保工作负荷较高的队列比工作负荷较小的队列受到更多关注。换句话说,Horizon将尝试在各个队列之间实现相等的等待时间。
一种不太复杂的方法是让队列工作者监听并在多个队列上工作。这可以通过将多个逗号分隔的队列传递到--queue
参数:--queue=high,low
这样做时,我们指示队列工作人员处理high
队列中的工作项目,优先于low
队列中的工作项目。这意味着在从high
队列开始工作之前,工作人员将始终彻底清除low
队列。如果在处理low
队列中的作业之后,工作人员在high
队列中找到了某个项目,那么他将跳回到该队列。因此,每次工作人员寻找新工作项目时,他都会首先在high
队列中查找,如果没有工作项目,他将进入low
队列。
对于上面的示例,我们可以例如部署以下6个队列工作器:
php artisan queue:work --queue=high,low
php artisan queue:work --queue=low
在这种情况下,high
队列比low
队列拥有更多的工作者资源。但是,如果资源没有任何优先工作要做,则这些资源将帮助low
队列中的其他工作。
我们当然也可以将high
队列作为后备添加到我们的low
队列工作器中:
php artisan queue:work --queue=high,low
php artisan queue:work --queue=low,high
这样,在工作量超载(例如上述销售情况)的情况下,他们将能够帮助我们的high
优先队列工人。
简单的解决方案通常会更好。当您的工作负载不会突然爆炸并且可以预测它们很好时,请采用第二种方法(但是请使用supervisor,这样您就不必一直手动启动工作人员并确保它们在崩溃时重新启动。
反之,如果您的工作负载变化很大,并且您无法真正预先告知需要多少个队列工作者,那么Horizon可能值得一看。就个人而言,我还可以将Horizon用于相当简单的项目,因为它易于设置,并且占用了我很多工作,而我不得不考虑很多有关负载和事物的事情。