【问题标题】:PHP + MySQL Cycle QueuePHP + MySQL 循环队列
【发布时间】:2009-11-06 23:54:32
【问题描述】:

我刚刚接受了一个类似的问题 (PHP + MySQL Queue),但我意识到这不是我的问题的正确问题,而是我问题的正确答案 :)

我有一个 MySQL(MyISAM 类型)网站要被工作人员抓取的表。

CREATE TABLE `site` (
  `id` int(11) NOT NULL auto_increment,
  `url` text,
  `last_pop` int(13) default NULL,
  `md5` varchar(32) default NULL,
  `disabled` tinyint(1) default '0',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `md5` (`md5`),
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;

我需要的是不重复地为每个工人报废一个站点。 所以,如果我有 3 个站点和 2 个工作人员,系统需要像这样工作:

      ID URL   LAST_POP
t4    1  site1 t1         <- worker1 scrap site1
t4    2  site2 t2         <- worker2 scrap site2
t5    3  site3 t3         <- worker1 scrap site3
t6    1  site2 t4         <- worker2 scrap site2
t6    2  site1 t4         <- worker1 scrap site1
t7    3  site3 t5         <- worker2 scrap site3
....

这就像 last_pop ASC 的循环队列排序器。

我该怎么做?

【问题讨论】:

    标签: php mysql queue cycle


    【解决方案1】:

    您可能希望跟踪每个站点的两条信息:上次抓取的时间以及当前是否正在抓取。

    使用其他问题的答案,将 scraping 字段设置为工作人员的 ID,以将其与其他工作人员锁定。当工作人员完成任务后,将scraping 字段设置回null,并将last_scrape 日期设置为当前时间。

    CREATE TABLE `site` (
      `id` int(11) NOT NULL auto_increment,
      `url` text,
      `last_scrape` TIMESTAMP,
      `scraping` tinyint(1) default NULL,
      `md5` varchar(32) default NULL,
      `disabled` tinyint(1) default '0',
      PRIMARY KEY  (`id`),
      UNIQUE KEY `md5` (`md5`),
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1;
    

    锁定并检索下一个作业(上次抓取时间最长的网站):

    Update site
      set `scraping` = '$worker_id' 
      where `scraping` is null 
      order by `last_scrape` ASC limit 1;
    
    $job = 
      Select * from site
      where `scraping` = '$worker_id'
    

    将作业释放回队列:

    Update site
      set `scraping` = NULL,
      `last_scrape` = NOW()
      where `scraping` = '$worker_id';
    

    【讨论】:

    • 您可以结合使用时间戳和抓取状态,只要它们的值不会冲突。如果您可能有 100 个工作人员,只需选择 last_scape > 101 的工作并将 last_scrape 设置为工作人员 id 最多 100 以指定正在处理它。确保您也将该字段初始化为更大的值,否则它们可能看起来已经对所有工作人员锁定。
    【解决方案2】:

    为什么不添加一个额外的布尔列 STATUS 以便您可以按 LAST_POP 排序。因此,当工作人员选择一个站点进行报废时,使用UPDATE site SET status = '1' 运行第二个查询。当下一个工作人员选择下一个站点时,使用SELECT * FROM site WHERE status = '0' ORDER BY last_pop ASC 运行查询。

    【讨论】:

      猜你喜欢
      • 2010-12-14
      • 2012-07-06
      • 1970-01-01
      • 2012-08-05
      • 2014-01-04
      • 2011-04-02
      • 2011-07-17
      • 2023-03-07
      • 1970-01-01
      相关资源
      最近更新 更多