PHP分叉和处理MySQL数据库没有冲突

时间:2013-02-09 20:32:58

标签: php mysql parallel-processing fork pcntl

我有一个我需要处理的MySQL数据库表。处理3行大约需要1秒钟(由于我需要为每一行进行CURL连接)。所以,我需要分叉PHP脚本以便有一个合理的时间(因为我将为一个批处理多达10,000行)。

我将同时运行10-30个进程,显然我需要一些方法来确保进程不重叠(就它们检索和修改的行而言)。

根据我的阅读,有三种方法可以实现这一目标。我正在尝试确定哪种方法最适合这种情况。

选项1:开始一个事务并使用SELECT ... FOR UPDATE并限制每个进程的行数。将数据保存到数组。使用状态标志“processing”更新选定的行。提交事务,然后将选定的行更新为“已完成”状态。

选项2:使用状态标志“处理”和进程ID更新一定数量的行。选择该进程ID和标志的所有行。正常处理数据。更新这些行并将标志设置为“已完成”。

选项3:为每个进程的LIMIT ... OFFSET ...查询设置SELECT子句,以便每个进程都可以使用唯一的行。然后存储行ID并在完成时执行UPDATE

我不确定哪个选项最安全。我认为选项3看起来很简单,但我想知道这有什么办法可能会失败吗?选项2看起来也很简单,但我不确定UPDATE引起的锁定是否导致一切都变慢。选项1似乎是最好的选择,但我对FOR UPDATE和交易不是很熟悉,并且可以使用一些帮助。

更新:为了清楚起见,我目前只有一个文件process.php,它选择所有行并通过Curl逐个将数据发布到第三方。我想在这个文件中有一个fork,所以10,000行可以分成10-30个子进程。

2 个答案:

答案 0 :(得分:0)

另一种处理方法是将需要处理的ID放入redis队列(列表)。然后,您可以从列表中弹出/推送项目。当len(list)为空时,您知道没有什么可以处理。

还有一个php resque项目,它将实现你想要做的一些工作排​​队。

https://github.com/chrisboulton/php-resque

答案 1 :(得分:0)

我最终使用mult_curl函数(由Brad提出)来完成此任务。我使用array_chunk()将行数组分成100个组,然后配置multi_curl任务来处理它们。我开始使用ParallelCurl,但它最终没有正常工作,所以我只是自己编写了mult_curl。

从花费近2个小时处理10,000个卷曲连接只需几分钟。