PHP并行/分布式工具;MySQL;如何在多台服务器上锁定一个功能


PHP Parallel/Distributed Tool & MySQL & How to lock a function across multiple servers

我一直在用MySQL后端构建PHP工具。使用multi-ccurl,我可以在一台旧电脑(现在运行最新的Ubuntu桌面)上同时运行几十个甚至数百个脚本。每台机器和每台机器上的每个虚拟机都能够运行数十个并发实例。

因此,我很快就用完了MySQL连接。当我增加MySQL中的连接数量时,我冻结了我用来托管MySQL服务器的四核机器。从那以后,我转向了一个方案,在这个方案中,我有一个特定于DB的数据库来管理其他DB的请求,并使用运行数小时的cron作业,我为每台机器维护一些打开的连接。在这一点上,我仍然处于轻度测试阶段,我还没有试图同时发出数百个请求来查看MySQL服务器如何处理它

相反,我遇到了另一个问题,我尝试了几种解决方案,结果大致相同。问题是重复的数据被输入到数据库中,因为我有在不同机器上运行的工具的并发实例。例如,我将一大块新数据输入数据库,这些数据需要执行一些任务,例如将电子邮件地址链接到用户配置文件。我选择让后台cron进程一次处理一点,每台机器每5分钟共享一次。由于它们都是在同一时间开始的,所以它们都会获取相同的电子邮件数据,并使用相同的逻辑对其进行过滤,以确定哪些电子邮件地址的优先级更高。然后,每台机器都开始处理它选择的电子邮件。由于它们都是在同一时间启动的,因此它们似乎经常获取完全相同的数据并尝试进行相同的链接。这会导致链接表中出现主键异常,但不会导致其他一些主键异常。因此,我最终在一些表中发现了重复的数据,偶尔还会出现不完整的链接。

我尝试过随机化SELECT数据,这样机器就可以处理不同的数据集。然而,就我希望该工具完成的任务而言,这当然是次优的,所以我需要更频繁地运行该工具,以便在所需的时间范围内完成某些任务。我尝试在DB中创建一个标志,指定1台服务器正在积极使用数据,因此所有其他服务器都应该等待。这有时有效,但有时两台机器同时轮询该标志。既然我们谈论的是多台机器,我不相信它们会工作。从我所读到的内容来看,将表锁定在DB中可能也不是一个好的解决方案。

因此,我来到StackOverflow寻求建议,而不是继续把头撞在墙上。

===更新===

Gearman看起来是一个很好的解决方案,所以我对它竖起了大拇指。然而,我从来没能让它与我的PHP安装一起工作。我在网上尝试了几套建议/说明,其中许多甚至从未安装gearman。据我所知,使用apt-get-installgearman服务器的建议确实安装了gearman,即没有生成错误,gearmand将运行。然而,当我试图在脚本中使用gearman客户端和worker时,我会遇到找不到这些类的错误。

之后,我将gearman.ini文件添加到正确的目录中。它有1条CCD_ 1。这导致了另一个错误,PHP告诉我找不到gearman.so。我试图使用sudo find / -name gearman.*找到gearman.sho,但没有成功——它返回了C文件,但没有返回gearman.seo。

在这个时候,我真的,真的,非常喜欢实现gearman,但由于我不能让它工作,我只能使用我的破解PHP代码来实现我的分布式工具集。到目前为止,我的"解决方案"是创建一个标志,当该工具的一个实例正在执行可能导致重复数据问题的操作时,该标志将设置为"占用"。我已经创建了5个相同的标志,后缀为_1、_2。。。从而可以同时运行5个实例。(我使用_1、_2、…在返回的DB数据中创建一个偏移量,这样就不会有2个工具实例在同一数据集上工作。换句话说,如果SELECT语句返回100多行,而我一次只处理10行,那么_1在1-10行上工作,_2在11-20行上工作……不理想,但它应该允许多个服务器同时在DB上操作,而不会创建重复的数据。)。)

如果DB API工具在30秒内没有看到结果,它就会超时。现在的问题是在试图获取这些标志状态时频繁超时。。。

您应该使用队列系统将每个数据集作为一个项目插入队列中,并使用分布式服务器设置从队列中提取作业并对数据库执行查询。使用队列将阻止多个工作人员执行相同的作业。

以Gearman为例进行

  • http://gearman.org/#how_does_gearman_work
  • http://us.php.net/gearman