PHP + MySQL Queue

Мне нужна простая таблица, которая действует как очередь. Мое ограничение сервера MySQL – я не могу использовать таблицы InnoDB, только MyISAM.

Клиенты / работники будут работать в одно и то же время, и им нужно будет получать разные задания каждый раз.

Моя идея – сделать следующее (псевдокод):

$job <- SELECT * FROM queue ORDER BY last_pop ASC LIMIT 1; UPDATE queue SET last_pop WHERE id = $job->id return $job 

Я попробовал блокировку таблицы и «GET_LOCK», но ничего не происходит, рабочие иногда получают одинаковые задания.

Вам нужно повернуть свой заказ, чтобы не было временного окна.

Потребительский POP (каждый потребитель имеет уникальный $ consumer_id)

 Update queue set last_pop = '$consumer_id' where last_pop is null order by id limit 1; $job = Select * from queue where last_pop = '$consumer_id' order by id desc limit 1; 

Поставщик PUSH

 insert into queue (id, last_pop, ...) values (NULL, NULL, ...); 

Очередь упорядочивается во времени столбцом id и назначается POP на user_id.

Просто для информации есть еще один вариант, который использует Gearman вместо таблицы, чтобы сделать очередь: Rasmus Lerdorf написал очень хорошую статью об этом .

Олег,

Решение правильное. $consumer_id должен быть уникальным идентификатором для процессора. Например, если у вас было несколько заданий cron на одной машине, вы могли бы использовать их pid в качестве consumer ID .

UPDATE является атомарным, поэтому он отмечает ровно одну строку в очереди как потребляемую вашим ID .

Для некоторых приложений у меня также есть поле состояния для завершенного , так что если last_pop's user_id установлен, но готовый флаг не установлен, а задание старше X, его можно пометить для перезапуска.