Я работаю над веб-сканером / пауком, и мне нужен какой-то способ эффективного массового хранения строк в качестве ссылки для (1) уже сохраненных сайтов и (2) очереди для моего сканера. Эти структуры хранения данных должны быть в состоянии хранить намного больше миллионов строковых значений. Я начну с исследования, которое я исследовал, и того, что я сделал соответственно.
Первый метод, который я попробовал, был связан с этим потоком
Java: оптимизировать хэш-сет для большихобнаружение дублирования в масштабе
В этой теме OP рассказывает об оптимизации HashSet и получил много хороших отзывов и предупреждений. HashSet был очень дорогим в использовании и вызывал очень быстрый сбой моей программы. В ответах были предложены альтернативы, такие как Trove, однако с тех пор проект был прекращен, и я считаю, что есть более лучшие альтернативы.
Второй метод, который я попробовал, состоял в том, чтобы создать очередь с использованием MongoDB. Я явно создал коллекцию для очереди, в которой следовал FIFO, так как Mongo использует блокировки, поэтому она должна быть поточно-ориентированной. И из того, что я мог сказать, это работало очень хорошо. Мой сканер работал очень хорошо и в среднем занимал очень мало памяти (12 ~ 42 МБ). Однако этот метод вскоре оказался очень плохим, так как MongoDB имеет скорость поиска o (n). Создание итератора, который проверяет две коллекции (коллекцию веб-сайтов и коллекцию очередей) для каждого веб-сайта, подлежащего кэшированию, оказалось очень вредным.
Следуя этой теме
Стратегии быстрого поиска миллиардов небольших документов в MongoDB
Это действительно улучшило поискКачество немного, но это было мягкое возмещение. Ниже приведен простой псевдокод моего веб-сканера.
while(true){
parse();
}
public void parse(){
String next = // next url in queue to be parsed
Document document = // get HTML dom from next url
// store document inside of site storage (mongo collection)
// grab links from document
for( all links found ) {
if(next doesn't exist in website collection and next isn't already in queue){
add to queue
}
}
}
Проверка "next не существует в коллекции веб-сайтов, а next еще не находится в очереди", мне нужно создать итератор или использоватьmongo.collection.find (). limit (1) (который также является итератором, за кулисами), чтобы проверить, существует ли следующий элемент внутри текущих сохраненных веб-сайтов или очереди. Итак, как вы можете видеть, по мере роста двух коллекций, в настоящее время насчитывающих более 100 000 записей в обеих, процессор может постоянно и медленно проверять обе коллекции.
Что возвращает меня к моему первомуметод, который удерживает потенциально до миллиардов URL-адресов в памяти для быстрого поиска дубликатов в обоих хранилищах. Большинство вещей, которые я прочитал, были очень полезны, но устарели, и мне было интересно, что вы, ребята, считаете лучшим способом для этого?