我有一个需要处理的 MySQL 数据库表。处理 3 行大约需要 1 秒(由于我需要为每一行建立 CURL 连接)。因此,我需要 fork PHP 脚本以便有合理的时间(因为我将处理一个批处理最多 10,000 行)。
我将同时运行 10-30 个进程,显然我需要一些方法来确保进程不重叠(根据它们正在检索和修改的行)。
根据我的阅读,可以通过三种方法来完成此操作。我正在尝试确定哪种方法最适合这种情况。
选项 1:开始事务并使用 SELECT ... FOR UPDATE
并限制每个进程的行数。将数据保存到数组中。使用状态标志“processing”更新所选行。提交事务,然后将所选行更新为“已完成”状态。
选项 2:使用状态标志“processing”和进程 ID 更新一定数量的行。选择该进程 ID 和标志的所有行。像往常一样处理数据。更新这些行并将标志设置为“完成”。
选项 3:为每个进程的 SELECT
查询设置一个 LIMIT ... OFFSET ...
子句,以便每个进程都具有唯一性要处理的行。然后存储行 ID 并在完成时执行 UPDATE
。
我不确定哪个选项最安全。我认为选项 3 看起来很简单,但我想知道有什么方法会失败吗?选项 2 似乎也很简单,但我不确定 UPDATE
导致的锁定是否会导致一切变慢。选项 1 似乎是最好的选择,但我对 FOR UPDATE
和交易不是很熟悉,需要一些帮助。
更新:为清楚起见,我目前只有一个文件 process.php,它选择所有行并通过 Curl 将数据逐一发布到第三方。我想在这个文件中创建一个分支,这样 10,000 行就可以分成 10-30 个子进程。
最佳答案
另一种处理方法是将需要处理的 id 放入 redis 队列(列表)中。然后您可以从列表中弹出/推送项目。当 len(list) 为空时,您知道没有任何东西需要处理。
还有 php resque 项目,它将实现您想要执行的一些作业排队。
关于PHP fork 处理MySQL数据库无冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14791275/