PHP + MySQL Queue

天大地大妈咪最大 提交于 2019-12-20 10:56:06

问题


I need a simple table that acts as a Queue. My MySQL server restriction is I can't use InnoDB tables, only MyISAM.

Clients/workers will work at the same time and they will need to receive differents jobs each time.

My idea is to do the following (pseudo-code):

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

I had tried table lock and "GET_LOCK" but nothing happends, workers sometimes receives same jobs.


回答1:


You need to turn your ordering around so there is no timing window.

Consumer POP (each consumer has a unique $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;

Supplier PUSH

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

The queue is ordered in time by the id column and assigned upon POP by to the consumer_id.




回答2:


Just for information, there's another option that is using Gearman instead of a table to make the queue: Rasmus Lerdorf wrote a very nice article about it.




回答3:


Oleg,

The solution is correct. $consumer_id must be a unique identifier for the processor. If you had a couple cron jobs on one machine, for example, you could use their pid as the consumer ID .

The UPDATE is atomic, so it marks exactly one row in the queue as being consumed by your ID.

For some applications I also have a status field for finished, so that if last_pop's consumer_id is set, but the finished flag is not set and the job is older than X, it can be marked to be restarted.



来源:https://stackoverflow.com/questions/1690748/php-mysql-queue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!