Php 选择+更新以避免返回相同的结果

Php 选择+更新以避免返回相同的结果,php,mysql,cron,queue,debian,Php,Mysql,Cron,Queue,Debian,我在n台服务器上每x秒运行一次cron任务。它将从time_scheduled的表中进行选择我猜您只有一个MySQL实例,并且有来自n台服务器的连接来运行此处理作业。您正在这里实现一个作业队列 您提到的表需要使用InnoDB访问方法或Percona或MariaDB提供的其他事务友好访问方法之一 表中的这些项目是否需要分批处理?也就是说,它们之间是否存在某种相互关联?或者您的服务器进程可以逐个处理它们吗?这是一个重要的问题,因为如果您可以单独或小批量处理服务器进程,您将在它们之间获得更好的负载平衡

我在n台服务器上每x秒运行一次cron任务。它将从time_scheduled的表中进行选择我猜您只有一个MySQL实例,并且有来自n台服务器的连接来运行此处理作业。您正在这里实现一个作业队列

您提到的表需要使用InnoDB访问方法或Percona或MariaDB提供的其他事务友好访问方法之一

表中的这些项目是否需要分批处理?也就是说,它们之间是否存在某种相互关联?或者您的服务器进程可以逐个处理它们吗?这是一个重要的问题,因为如果您可以单独或小批量处理服务器进程,您将在它们之间获得更好的负载平衡。让我们假设小批量

这样做的目的是防止任何服务器进程在其他服务器进程拥有某一行时抓住表中的某一行。我已经做了很多这样的事情,这里是我的建议;我知道这很管用

首先,向表中添加一个整数列。称之为工作或诸如此类的事情。给它一个默认值零

其次,为每个服务器分配一个永久id号。服务器IP地址的最后一部分例如,如果服务器的IP地址为10.1.0.123,则id号为123是一个不错的选择,因为它在您的环境中可能是唯一的

然后,当服务器的抓取工作要做时,使用这两个SQL查询

  UPDATE table
     SET working = :this_server_id
   WHERE working = 0
     AND time_scheduled < CURRENT_TIME
   ORDER BY time_scheduled
   LIMIT 1

  SELECT table_id, whatever, whatever
    FROM table
   WHERE working = :this_server_id
就这样

除了一件事。在现实世界中,这些排队系统有时会出错。服务器进程崩溃。参见墨菲定律。您需要一个监视查询。这在这个系统中很容易

此查询将列出所有逾期五分钟以上的作业,以及应该处理这些作业的服务器

 SELECT working, COUNT(*) stale_jobs
   FROM table
  WHERE time_scheduled < CURRENT_TIME - INTERVAL 5 MINUTE
  GROUP BY WORKING

顺便说一句,一个关于工作、时间安排的复合索引可能有助于更好地执行此操作。

mysql服务器在所有服务器之间共享?是的,它们都来自同一个服务器。我认为这可能会很好地工作。我会设法实施它,看看是否遇到任何未预料到的问题。非常感谢。结果很好。再次感谢。
 SELECT working, COUNT(*) stale_jobs
   FROM table
  WHERE time_scheduled < CURRENT_TIME - INTERVAL 5 MINUTE
  GROUP BY WORKING
  UPDATE table
     SET working=0
   WHERE working=?server_id_at_lunch