Назад | Перейти на главную страницу

Самый эффективный (по времени, стоимости) способ очистить 5 миллионов веб-страниц?

У меня есть список веб-страниц, которые мне нужно очистить, проанализировать и затем сохранить полученные данные в базе данных. Всего около 5 000 000 человек.

Мое текущее предположение о том, что лучший способ приблизиться к этому - развернуть ~ 100 экземпляров EC2, предоставить каждому экземпляру 50 000 страниц для очистки, а затем оставить его запускаться, а затем, когда процесс будет завершен, объединить базы данных вместе. Предполагается, что это займет около одного дня (600 мсек на загрузку, синтаксический анализ и сохранение каждой страницы).

У кого-нибудь есть опыт выполнения такого большого объема парсинга страниц за ограниченное время? Раньше я делал большие числа (1,5 млн), но это было на одной машине, и это заняло чуть больше недели.

Узким местом в моей ситуации является загрузка страниц, синтаксический анализ - это то, что занимает не более 2 мс, поэтому я ищу то, что может упростить процесс загрузки страниц.

Исходя из предположения, что время загрузки (и, следовательно, использование полосы пропускания) является вашим ограничивающим фактором, я бы сделал следующие предложения:

Сначала выберите экземпляры m1.large. Из трех «уровней» производительности ввода-вывода (включая полосу пропускания) экземпляры m1.large и m1.xlarge оба предлагают «высокую» производительность ввода-вывода. Поскольку ваша задача не связана с процессором, наиболее предпочтительным вариантом будет наименее затратный из них.

Во-вторых, ваш экземпляр сможет загружаться намного быстрее, чем любой сайт может обслуживать страницы - не загружайте по одной странице за раз в данном экземпляре, запускайте задачу одновременно - вы должны иметь возможность одновременно выполнять не менее 20 страниц (хотя , Я думаю, вы можете без труда сделать 50-100). (Возьмите пример загрузки с форума из вашего комментария - это динамическая страница, для создания которой потребуется время сервера - и есть другие пользователи, использующие пропускную способность этого сайта и т. Д.). Продолжайте увеличивать параллелизм, пока не достигнете пределов пропускной способности экземпляра. (Конечно, не делайте несколько одновременных запросов к одному и тому же сайту).

Если вы действительно пытаетесь максимизировать производительность, вы можете рассмотреть возможность запуска экземпляров в географически подходящих зонах, чтобы минимизировать задержку (но для этого потребуется геолокация всех ваших URL-адресов, что может оказаться непрактичным).

Следует отметить, что пропускная способность экземпляра является переменной, иногда вы получаете более высокую производительность, а в других случаях - более низкую. В меньших экземплярах разница в производительности более значительна, поскольку физические каналы используются большим количеством серверов, и любой из них может снизить доступную пропускную способность. Между экземплярами m1.large в сети EC2 (одна и та же зона доступности) вы должны получить пропускную способность, близкую к теоретической гигабитной.

В целом, с AWS почти всегда более эффективно использовать более крупный экземпляр, чем несколько меньших экземпляров (если вы специально не рассматриваете что-то вроде аварийного переключения и т. Д., Где вам нужно несколько экземпляров).

Я не знаю, что влечет за собой ваша настройка, но когда я ранее пытался это (от 1 до 2 миллионов ссылок, периодически обновляемых), мой подход заключался в том, чтобы поддерживать базу данных ссылок, добавляя новые ссылки по мере их обнаружения и разветвляя процессы чтобы очистить и проанализировать страницы. URL-адрес будет извлечен (случайным образом) и помечен как обрабатываемый в базе данных, сценарий загрузит страницу и в случае успеха пометит URL-адрес как загруженный в базе данных и отправит содержимое другому сценарию, который проанализировал страницу, новые ссылки были добавлены в базу данных по мере их обнаружения. Преимуществом базы данных здесь была централизация - несколько сценариев могли одновременно запрашивать базу данных и (пока транзакции были атомарными) можно было быть уверенным, что каждая страница будет загружена только один раз.

Несколько дополнительных моментов упоминания - существуют ограничения (я считаю, 20) на количество инстансов по запросу, которые вы можете запускать одновременно - если вы планируете превысить эти ограничения, вам нужно будет запросить AWS для увеличения пределы. Было бы намного экономичнее запускать спотовые инстансы и увеличивать количество, когда спотовая цена низкая (возможно, один инстанс по требованию, чтобы все было организовано, а остальные спотовые инстансы).

Если время для вас важнее затрат, вычислительные инстансы кластера предлагают пропускную способность 10 Гбит / с - и должны обеспечивать максимальную пропускную способность для загрузки.

Резюме: попробуйте несколько больших экземпляров (вместо множества маленьких) и запустите несколько одновременных загрузок для каждого экземпляра - добавьте больше экземпляров, если вы обнаружите, что пропускная способность ограничена, переходите к более крупным экземплярам, ​​если вы обнаружите, что у вас ограничены ЦП / память.

Мы попробовали сделать что-то подобное, и вот мои 5 центов:

  1. Получите 2-3 дешевых безлимитных сервера, например не платите за пропускную способность.

  2. Используйте python с asyncore. Asyncore - это старый способ решения задач, но мы обнаружили, что он работает быстрее, чем любой другой метод. Обратной стороной является то, что поиск DNS является блокирующим, т.е. не «параллельным». Используя asyncore, нам удалось очистить 1M URL за 40 минут, используя одно ядро ​​XEON 4, 8 ГБ ОЗУ. Средняя нагрузка на сервер была меньше 4 (что отлично для 4 ядер).

  3. Если вам не нравится asyncore, попробуйте gevent. Он даже DNS не блокирует. Используя gevent, 1M загружался примерно за 50 минут на то же оборудование. Средняя нагрузка на сервер была огромной.

Обратите внимание, что мы протестировали множество библиотек Python, таких как grequests, curl, liburl / liburl2, но мы не тестировал Twisted.

  1. Мы протестировали PHP + curl + несколько процессов, он работал около часа, но средняя нагрузка на сервер была огромной.