2009-11-06 2 views
1

Я только что принял подобный вопрос (PHP + MySQL Queue), но я понял, что это не правильный вопрос для моей проблемы, но правильный ответ на мой вопрос :)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.

Как я могу это сделать?

ответ

1

Возможно, вам захочется отслеживать две части информации для каждого сайта: когда она была последней скребли, и если она в настоящее время очищается.

Используя ответ на свой другой вопрос, установите поле scraping идентификатору рабочего, чтобы заблокировать его от других работников. Когда работник закончит задание, установите поле 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'; 
+0

вы могли бы потенциально объединить использование отметки времени и выскабливания, если их значения не будут конфликтовать. Если у вас может быть 100 рабочих, просто выберите задание, где 'last_scape'> 101, и установите' last_scrape' для идентификатора рабочего пользователя до 100, чтобы указать, что он обрабатывается. Удостоверьтесь, что вы также инициализируете поле большим значением, или они могут казаться уже заблокированными для всех работников. – gapple

+0

это достаточно хорошо. Благодарю. – inakiabt

0

Почему бы не добавить дополнительный булевой столбцы STATUS, чтобы вы могли заказать LAST_POP. Поэтому, когда сайт выбирает работник для утилизации, запустите второй запрос с UPDATE site SET status = '1'. И когда следующий рабочий выбирает следующий сайт, запустите запрос с SELECT * FROM site WHERE status = '0' ORDER BY last_pop ASC.

Смежные вопросы