Очередь Redis с истечением срока действия заявки - PullRequest
4 голосов
/ 02 октября 2011

У меня есть интерфейс очереди, который я хочу реализовать в Redis.Хитрость заключается в том, что каждый работник может претендовать на предмет в течение N секунд, после чего предполагается, что работник потерпел крах, и предмет должен быть снова востребован.Ответственность за удаление предмета по окончании лежит на работнике.Как бы вы сделали это в Redis?Я использую phpredis, но это неважно.

Ответы [ 2 ]

3 голосов
/ 19 декабря 2011

Чтобы реализовать простую очередь в 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
1 голос
/ 03 октября 2011

Вы можете установить стандартную синхронизированную схему блокировки в Redis с помощью [SETNX][1]. По сути, вы используете SETNX для создания блокировки, которую каждый пытается получить. Чтобы снять блокировку, вы можете DEL установить ее, а также настроить EXPIRE, чтобы сделать блокировку снятой. Здесь есть и другие соображения, но нет ничего необычного в настройке блокировки и критических секций в распределенном приложении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...