从Laravel Redis队列中删除重复的作业

时间:2020-07-27 19:40:32

标签: laravel redis

我有一个可调度的工作,以清除和重建特定模型的缓存。

重建缓存大约需要10秒钟。

有时(有时)顺序地解雇该作业,而我经常会遇到多个排队的作业,所有作业都针对同一模型进行相同的缓存清除和重建。

我正在寻找一种在分派当前作业之前删除该特定模型的任何相同作业(缓存重建)的方法。

3 个答案:

答案 0 :(得分:1)

没有简单或%100的工作方式来删除重复的作业。 Laravel的Redis队列驱动程序将排序后的集合和列表用于延迟/不延迟的作业。该answer可能会提供一些有关它的细节。当您将作业推送到队列中时,您将无法在处理之前将其删除。 (您可以尝试,但是很难找到链接的答案)。

您可能要做的是创建一种控制机制,以防止触发缓存无效作业。假设在推进工作之前,您已经设置了唯一的标识符。您可以将Redis的SET命令与EXNX选项一起使用。

  • 设置键以保存字符串值。如果键已经包含一个值,则无论其类型如何,它都会被覆盖。
  • NX-仅设置不存在的密钥。
  • EX秒-设置指定的到期时间(以秒为单位)。

在执行工作之前,您要执行第一个命令,如下所示:

127.0.0.1:6379> set mymodel:id:1 some-random-string-test EX 15 NX
OK
127.0.0.1:6379> ttl mymodel:id:1
(integer) 10
127.0.0.1:6379> get mymodel:id:1
"some-random-string-test"
127.0.0.1:6379> set mymodel:id:1 some-random-string-test-another EX 15 NX
(nil)
127.0.0.1:6379>

您正在做的是,获得模型的id并创建一个密钥。您可以使用expire和set if not exists选项设置密钥。如果响应为OK,则您将在给定的时间间隔(在我的示例中为15秒)内首次设置此键。如果收到nil响应,则意味着给定ID的作业仍为locked。因此,您将不会分派它。它将为您提供每个模型15秒的时间窗口,以防止您分派它。

-

如果您不能(不想)阻止该作业被触发,则可以以不同的方式使用相同的命令。每当您要分派作业时,都将创建一个唯一的标识符,并在分派作业之前执行set mymodel:id:1 some-random-string-test EX 15 NX。但是这次,您也将标识符发送给作业的构造函数。在handle方法的开始,您将使用redis的GET方法来获取mymodel:id:1的值,并将其与发送给作业的构造函数的标识符进行比较。 15秒内将只有1个匹配的标识符,这意味着将仅“完全”处理一个作业。为相同作业创建的其他标识符将不会更新该Redis键(NX选项)的值,因此其他作业的标识符将与mymodel:id:1的值不匹配。这意味着它们将被取消或未完全处理,因为它们将不符合条件。

答案 1 :(得分:0)

请考虑在phpredis连接上使用setnx命令。
注意。这与--tries命令中的php artisan queue:work选项不同,并且重试失败的作业

enter image description here

答案 2 :(得分:-1)

尝试为每个作业使用不同的队列(例如:每个模型的队列),以便您可以使用 Queue::size('queue_name'),然后再分派新作业。