【发布时间】:2012-03-13 18:51:19
【问题描述】:
我一直在使用 MySQL 后端构建 PHP 工具。使用 multi-curl,我可以在一台旧 PC(现在运行最新的 Ubuntu 桌面)上同时运行数十个甚至数百个脚本。每台机器和每台机器上的每个虚拟机都能够运行数十个并发实例。
结果我很快就用完了 MySQL 连接。当我增加 MySQL 中的连接数时,我冻结了用于托管 MySQL 服务器的四核机器。从那时起,我转向了一个方案,其中我有一个专门用于管理其他数据库请求的数据库,并使用运行数小时的 cron 作业,我为每台机器维护一些打开的连接。在这一点上,我仍处于轻度测试阶段,我还没有尝试同时发出数百个请求来查看 MySQL 服务器如何处理它。
相反,我遇到了另一个问题,我尝试了几种解决方案,结果大致相同。问题是重复数据被输入到数据库中,因为我在不同的机器上运行了该工具的并发实例。例如,我将一大块新数据输入到我的数据库中,并且需要对这些数据执行一些任务,例如将电子邮件地址链接到用户配置文件。我选择让后台 cron 进程一次处理一点,每台机器每 5 分钟共享一次。由于它们都是同时开始的,它们都抓取相同的电子邮件数据,并使用相同的逻辑过滤哪些电子邮件地址具有更高的优先级。然后每台机器开始使用它挑选的电子邮件做需要做的事情。由于它们都是同时启动的,因此它们似乎经常抓取完全相同的数据并尝试进行相同的链接。这会导致链接表中的主键异常,但不会导致其他一些异常。因此,我最终会在某些表中出现重复数据,并且有时会出现不完整的链接。
我尝试将 SELECT 数据随机化,以便机器处理不同的数据集。但是,这对于我希望该工具完成的工作当然不是最佳的,因此我需要更频繁地运行该工具,以便某些任务在所需的时间范围内完成。我尝试在数据库中创建一个标志,指定 1 个服务器正在积极使用数据,因此所有其他服务器都应该等待。这有时有效,但有时两台机器同时轮询该标志。由于我们正在谈论多台机器,因此我不会蜂拥而至。从我读过的内容来看,锁定数据库中的表可能也不是一个好的解决方案。
所以我来 StackOverflow 寻求建议,而不是继续拼命撞墙。
== 更新 ==
Gearman 看起来是一个很好的解决方案,所以我给它竖起大拇指作为答案。但是,我永远无法让它与我的 PHP 安装一起使用。我在网上尝试了几组建议/说明,其中许多甚至从未安装过 gearman。据我所知,使用 apt-get install gearman-server 的建议确实安装了 gearman - 即没有产生错误并且 gearmand 会运行。但是,当我尝试在脚本中使用 gearman 客户端和 worker 时,我会收到关于无法找到这些类的错误。
之后,我将 gearman.ini 文件添加到正确的目录中。它有 1 行 extension=gearman.so。这导致了一个不同的错误,PHP 告诉我它找不到 gearman.so。我尝试使用sudo find / -name gearman.* 查找 gearman.so,但没有成功 - 它返回了 C 文件,但没有返回 gearman.so。
此时我非常非常非常喜欢实现 gearman,但由于我无法让它工作,所以我坚持使用我的 hack 和 slash PHP 代码来实现我的分布式工具集。迄今为止,我的“解决方案”是创建一个标志,当该工具的 1 个实例正在执行会导致重复数据问题的操作时将其设置为“OCCUPIED”。我创建了 5 个后缀为 _1、_2、... 的相同标志,以便 5 个实例可以同时运行。 (我使用 _1, _2, ... 在返回的 DB 数据中创建偏移量,以便没有 2 个工具实例在同一个数据集上工作。换句话说,如果 SELECT 语句将返回 100+ 行并且我只一次在 10 个上工作,然后 _1 在第 1-10 行上工作,_2 在 11-20 行上工作,......不理想,但它应该允许多个服务器同时在数据库上运行而不会创建重复数据。)
如果 DB API 工具在 30 秒内没有看到结果,则会超时。现在的问题是尝试获取这些标志状态时经常超时...
【问题讨论】:
标签: php mysql parallel-processing distributed conflict