LAMP堆栈-因此代码是PHP

我有一个innodb表-称为queueTable

有一个cron作业,每15分钟运行一次,查询数据库,以查明是否需要将任何记录放入queueTable中。有时没有添加到queueTable的记录,有时,可能有超过1,000条记录添加到queueTable。

需要发生的是,必须读取queueTable中的每一行,需要执行一个过程,然后再删除该行。

当前,我有两个守护程序作业,除了每5秒查询queueTable之外什么也不做。

一个作业读取所有奇数行记录,另一作业读取所有偶数行记录。为了快速完成所有处理,有两个作业(两个作业胜于一个作业)。

我想创建大约20个守护进程,所有守护进程都放在queueTable中-这样可以将一行在queueTable中的停留时间减至最少。

可以将其视为邮件队列(不是,但这只是一个很好的示例而已)。

我需要尽快清空队列。

我可以进行事务处理并锁定行,但这不会阻止另一个守护程序尝试锁定同一行。如果守护程序试图读取锁定的行,将会发生—它会等待它。但是锁定该行的守护程序将删除它。不确定第二个守护程序在那个时候做什么?

完成我想做的最好的方法是什么?

我希望这是有道理的。

谢谢!

顺便说一句-我尝试过pthreads-发现它确实对吞吐量没有太大帮助。 IE浏览器读取记录并在获得下一条记录之前对其进行处理的过程-如果我在多线程模式下执行此操作(即,每个进程是一个新线程),则清空队列的时间与在每一行执行的时间相同一个时间。至少在我的测试中是这样。

最佳答案

我在MySQL中实现队列的口头禅:“不要排队,就去做吧!”

用PHP进行多重处理并非易事。 Perl(也是Lamp的一部分)要好得多。此外,由于这是一项后台任务,因此请不要将Web服务器和浏览器(Apache + IE)放在外面。他们的开销很大。

处理一个“项目”需要多长时间?如果仅需几秒钟,则BEGIN; SELECT one item FOR UPDATE; process it; COMMIT;

如果花费的时间更长,请不要在所有内容旁加上BEGIN...COMMIT;而是做类似的事情:

SET autocommit=1


$id = SELECT id ... WHERE process_id IS NULL ORDER BY ... LIMIT 1;(或者,您可以抓10个,并具有步骤2..5的内部循环。)
UPDATE ... SET process_id = $pid WHERE id = $id AND process_id IS NULL;并检查其是否有效。请注意,SELECTUPDATE故意不在事务中。这是为了最大程度地减少干扰。但是,如果没有事务,则另一个线程有机会抓住它。如果是这样,则rows_affected将为0;否则为0。返回步骤1。
处理项目
UPDATE (or DELETE) ... SET process_id = NULL WHERE id = $item;-解除锁定
sleep(1)-稍微延迟-避免人为地淹没系统。这可能需要调整。
返回步骤1。


您可以有任意多个线程来执行此操作。

关于mysql - 如何使用PHP执行MySQL行锁定和删除行?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31278918/

10-11 18:38