[Хотя это старый вопрос, я добавляю этот ответ для поисковиков, приземляющихся здесь]
Вам нужен Фильтр Блума .
Хотя большинство фильтров Блума с открытым исходным кодом, которые вы найдете, представляют собой библиотеки, предназначенные для локального доступа, на самом деле довольно просто превратить их в веб-службу и, следовательно, в общий ресурс для нескольких узлов.
Вот очень простой пример использования php-bloom-filter со статической библиотекой кэша:
<?php
// assumes $_POST contains a JSON-encoded array of URLs to check ($links)
// and a unique crawl identifier ($crawl_id)
extract($_POST);
if (!$b = unserialize(Cache::read('filter_'.$crawl_id))) {
$b = new BloomFilter(100000, 0.001);
}
$return = array();
foreach (json_decode($links, true) as $link) {
if (!$b->has($crawl_id.'_'.$link)) {
$return[] = $link;
$b->add($crawl_id.'_'.$link);
}
}
// put the filter back into our cache
Cache::write('filter_'.$crawl_id, serialize($b));
echo json_encode($return);
Любые URL-адреса, которые выходят из проверки фильтра Блума, будут затем помещаться вВаша очередь сканирования для захвата узлами сканирования.
Этот вид реализации, очевидно, не предназначен для сканирований в масштабах сети, но будет подходящим для сканирования отдельных сайтов объемом до 100 000 страниц или более (в зависимости от доступныхресурсы сервера).Конечно, если вам действительно нужен ваш фильтр Блума для горизонтального масштабирования, вы можете использовать несколько узлов Блума за прокси-сервером, используя распределенный кэш некоторого описания (redis / memcache / ehcache и т. Д.).Вам понадобится умный осколок для объектов кеша, чтобы поддерживать скорость поиска, но я уверен, что вы справитесь с этим, когда возникнет такая необходимость.
Единственное предостережение по поводу вышесказанного - иногда вы получаете ложноеотрицательный результат и в конечном итоге сканирует один и тот же URL более одного раза - это факт большинства сканеров веб-страниц, так что это просто тот случай, когда вы должны изящно обработать код разбора сканирования.