У меня есть список веб-страниц, которые мне нужно очистить, проанализировать и затем сохранить полученные данные в базе данных. Всего около 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 центов:
Получите 2-3 дешевых неизмеренных сервера, например, не платите за пропускную способность.
Используйте Python с Asyncore. Asyncore - это старый способ работы, но мы обнаружили, что он работает быстрее, чем любой другой метод. Недостатком является то, что поиск DNS является блокирующим, то есть не «параллельным». Используя asyncore, нам удалось очистить 1M URL за 40 минут, используя одно ядро XEON 4, 8 ГБ ОЗУ. Средняя нагрузка на сервер была меньше 4 (что отлично для 4 ядер).
Если вам не нравится asyncore, попробуйте gevent. Это даже делает DNS неблокирующим. Используя gevent, 1M загружался в течение примерно 50 минут на том же оборудовании. Средняя нагрузка на сервер была огромной.
Обратите внимание, что мы протестировали множество библиотек Python, таких как grequests, curl, liburl / liburl2, но мы не тестировали Twisted .
источник