2

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

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

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

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

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

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

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

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

4

2 回答 2

0

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

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

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

于 2013-02-13T05:38:36.227 回答
0

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

处理 10,000 个 curl 连接需要将近 2 个小时,而现在只需几分钟。

于 2013-02-13T16:45:23.123 回答