1

同様の質問(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;

私が必要としているのは、ワーカーごとに 1 つのサイトを繰り返さずに廃棄することです。したがって、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 による循環キュー オーダラーのようなものです。

どうやってやるの?

4

2 に答える 2

1

おそらく、各サイトの 2 つの情報 (最後にスクレイピングされたときと現在スクレイピングされているかどうか) を追跡する必要があります。

他の質問の回答を使用して、scrapingフィールドをワーカーの ID に設定し、他のワーカーからロックします。ワーカーがタスクを終了したら、scrapingフィールドを元に戻しnulllast_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';
于 2009-11-07T00:14:04.270 に答える
0

LAST_POP で注文できるように、ブール列 STATUS を追加してみませんか。そのため、労働者が廃棄のためにサイトを選択すると、 で 2 番目のクエリを実行しますUPDATE site SET status = '1'。そして、次のワーカーが次のサイトを選択すると、 でクエリを実行しますSELECT * FROM site WHERE status = '0' ORDER BY last_pop ASC

于 2009-11-07T00:09:10.860 に答える