一尘不染

具有索赔的Redis队列已过期

redis

我有一个队列接口,我想在Redis中实现。诀窍在于,每个工人可以在假定该工人坠毁后需要N秒钟的时间索取一件物品,并且该物品需要再次索取。完成后移走物品是工人的责任。您将如何在Redis中做到这一点?我正在使用phpredis,但这是无关紧要的。


阅读 266

收藏
2020-06-20

共1个答案

一尘不染

为了在redis中实现一个简单的队列,该队列可用于重新提交崩溃的作业,我会尝试如下操作:

  • 1个清单“ up_for_grabs”
  • 1个清单“ being_worked_on”
  • 自动过期锁

试图找工作的工人会做这样的事情:

timeout = 3600
#wrap this in a transaction so our cleanup wont kill the task
#Move the job away from the queue so nobody else tries to claim it
job = RPOPLPUSH(up_for_grabs, being_worked_on)
#Set a lock and expire it, the value tells us when that job will time out. This can be arbitrary though
SETEX('lock:' + job, Time.now + timeout, timeout)
#our application logic
do_work(job)

#Remove the finished item from the queue.
LREM being_worked_on -1 job
#Delete the item's lock. If it crashes here, the expire will take care of it
DEL('lock:' + job)

而且不时地,我们只需获取清单并检查其中的所有作业实际上是否都已锁定。如果我们发现没有锁的任何作业,则意味着该作业已过期,我们的工作人员很可能崩溃了。在这种情况下,我们将重新提交。

这将是伪代码:

loop do
    items = LRANGE(being_worked_on, 0, -1)
    items.each do |job| 
        if !(EXISTS("lock:" + job))
            puts "We found a job that didn't have a lock, resubmitting"
            LREM being_worked_on -1 job
            LPUSH(up_for_grabs, job)
        end
    end
    sleep 60
end
2020-06-20