Проблемы с производительностью парсинга веб-страниц EC2 по сравнению с домашним ПК

Я написал веб-скрапер на Python, который очень хорошо работает на моем домашнем ноутбуке. После его развертывания на AWS EC2 производительность парсера ухудшается. Теперь я запутался в производительности экземпляров EC2 (даже микро- и малых экземпляров, см. подробности ниже).

Скребок в python: как правило, внутренний цикл скрапинга делает следующее: (1) скребок ищет URL-адреса на сайте (20 на сайт, один сайт = один site_break). На втором этапе он (2) получает исходный код каждого URL-адреса, на третьем этапе он (3) извлекает необходимую информацию в кадр данных, а на четвертом этапе он (4) сохраняет кадр данных как pkl. После всех циклов он открывает и объединяет кадры данных и сохраняет их как csv.

Важнейшими (наиболее трудоемкими частями) являются: (2) загрузка исходных кодов (ввод-вывод ограничен скоростью загрузки): программа заполняет ОЗУ исходным кодом (3) обработка исходных кодов (ЦП 100%)

Чтобы полностью использовать оперативную память и склеить похожие процессы, каждый цикл состоит из site_break = 100, т.е. 100 сайтов * 20 урлов/сайт = 2000 урлов. Это заполняет оперативную память моего ПК на 96% (см. ниже). Поскольку на шаге 1 и шаге 2 мне приходится ждать ответов сервера, я реализовал многопоточность с maxWorkers=15 (альтернативно 20-35 с аналогичными результатами). Эта реализация сокращает время выполнения на 80%. Я уверен, что смогу получить другие .%, внедрив asyncio. Тем не менее, я хочу начать с бережливого MVP. В процессоре, потребляющем шаг 3, я не реализовал многопроцессорность (пока), потому что моей целью была экономичная/бесплатная реализация на t2.micro (всего с одним процессором).

Спецификация: Домашний ПК: ЦП Intel Core i7-6500, 2,59 ГГц (2 ядра, 4 логических процессора), ОЗУ 8,00 ГиБ, 64-разрядная версия, x64, 50 Мбит/с Скорость загрузки (фактически до 45 Мбит/с), Python 3.7.3, окружение conda

EC2 t2.micro: vCPU = 1, RAM 1,0 ГиБ, производительность сети от низкой до умеренной (исследования на форумах говорят, что это может быть что-то выше 50 Мбит), Ubuntu 18.04, Python 3.7.3, conda env

EC2 t3a.small: vCPU = 2, RAM 2,0 ГиБ, производительность сети от низкой до умеренной, но другой сайт AWS сообщает мне: до 5 Гбит/с, Ubuntu 18.04, Python 3.7.3, conda env

Поскольку оперативная память t2.micro составляет всего 1 ГБ, я уменьшил site_break со 100 до 25. После этого оперативная память все еще заполнялась, поэтому я уменьшил ее на следующих шагах с 25 до 15, 12, 10 и, наконец, 5. Для 12, 10 и особенно для 5 это работает очень хорошо: мне понадобилось 5:30 минут для цикла с site_break = 100 на моем ПК. t2.micro требуется 8-10 секунд для site_break = 5, что приводит к 3 часам минуты для аналогичных 100 сайтов, что меня удовлетворило в первый момент. К сожалению, возникает следующая проблема: После 20-30 циклов производительность резко падает. Время включения цикла быстро увеличивается с 8 секунд до более чем 2 минут. Мое первое предположение заключалось в том, что это нехватка оперативной памяти, во время небольших циклов она не кажется заполненной. После остановки и очистки ОЗУ производительность падает после второго-третьего цикла. Если я запускаю его через несколько часов, то первый случай (с падением после 20-30 петель) повторяется.

Поскольку я сначала подумал, что это связано с оперативной памятью, я запустил второй экземпляр на t3a.small с большим процессором, оперативной памятью и производительностью сети до 5 Гбит/с. Я нарезал до site_break = 25 и запустил скрипт. Я все еще бегу с постоянной скоростью 1:39-1:55 мин на цикл (что вдвое меньше, чем у t2.micro в его лучшей фазе (10 сек на 5 => 50 сек на 25). Параллельно я начал скрипт с моего домашнего ПК с site_break = 25, и он постоянно быстрее с 1:15-1:30 минут на цикл (остановка времени вручную приводит к замедлению загрузки на 10-15 секунд и замедлению обработки на 10-15 секунд). смущает меня.

Теперь мои вопросы:

  1. Почему t2.micro ухудшается после нескольких циклов и почему производительность так сильно различается?
  2. Почему t3a.small на 50% медленнее, чем t2.micro? Я бы предположил, что большая машина будет быстрее в любом отношении.

Это позволяет мне застрять:

  1. Не хочу использовать свой домашний ПК для регулярного (ежедневного парсинга), так как соединение обрывается в 4 утра на крошечный промежуток времени и приводит к зависанию скрипта). Кроме того, я не хочу, чтобы скрипт запускался вручную и на ПК все время и блокировал мой частный интернет-поток.

  2. t2.micro: Бесполезно, потому что производительность после ухудшения неприемлема.

  3. t3a.small: производительность на 10-20% ниже, чем у частного ПК. Я ожидал, что это будет лучше как-то? Это позволяет моим сомнениям очистить по поводу EC2. Более того, я не могу понять более низкую производительность по сравнению с t2.micro в начале.


person MaGarb    schedule 24.06.2019    source источник
comment
Микро- и малые машины гораздо более ограничены, чем типичный домашний ПК. Потому что их типичный вариант использования — использование небольшого или среднего веб-сервера, для которого не требуется много лошадиных сил. Их процессорное время также распределяется и регулируется между многими экземплярами, и вы увидите, что ваша производительность значительно снизится, если вы продолжите использовать 100% ЦП в течение длительного времени.   -  person deceze♦    schedule 24.06.2019
comment
Попробуйте поэкспериментировать с разными типами экземпляров (особенно с разными семействами экземпляров). Вы можете использовать спотовые инстансы для снижения затрат, поэтому вы можете попробовать несколько действительно больших инстансов, чтобы увидеть, работают ли они лучше с точки зрения затрат на одного работника.   -  person John Rotenstein    schedule 24.06.2019
comment
Чтобы добавить к тому, что сказал @deceze, экземпляры T фактически дают вам часть ЦП см. документы. Они подходят только для рабочих нагрузок, которым требуется прерывистая загрузка ЦП, а не то, что постоянно работает на 100%.   -  person kdgregory    schedule 24.06.2019
comment
Что касается t3a: a означает, что он использует процессор ARM. Вы, вероятно, можете найти тесты, сравнивающие ARM и Intel, хотя любые такие тесты могут не соответствовать вашей рабочей нагрузке.   -  person kdgregory    schedule 24.06.2019
comment
Спасибо за ответы: поскольку мой скрипт работает несколько часов, я не уверен, подходят ли спотовые инстансы? Что, если я начну задание на экземпляре по требованию. Во время выполнения задания спотовая цена забронированного инстанса падает, и инстанс будет запущен. Движется ли работающий сценарий? Разве мне не нужно виндизировать экземпляр, чтобы скопировать env и модули? Что делать, если задание начинается на спотовом инстансе, который будет остановлен до завершения? Что происходит с промежуточными результатами/данными по экземпляру?   -  person MaGarb    schedule 24.06.2019
comment
Я думаю, вам нужно гораздо больше данных о том, что делают машины. например запустите что-то вроде vmstat 2 и посмотрите, что на самом деле делают машины, то есть привязаны ли вы к IO/CPU и в какие моменты. обратите внимание, что оперативная память никогда не заполняется, и вам, вероятно, нужна лучшая метрика для этого (например, количество страниц, которые заменяются на/с диска в секунду)   -  person Sam Mason    schedule 24.06.2019


Ответы (2)


  1. Почему t2.micro ухудшается после нескольких циклов и почему производительность так сильно различается?

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

  1. Почему t3a.small на 50% медленнее, чем t2.micro? Я бы предположил, что большая машина будет быстрее в любом отношении.

Инстансы T3 предназначены для приложений с умеренным использованием ЦП, которые испытывают временные всплески нагрузки. С t3 вы либо платите больше, чтобы иметь возможность позволить себе более крупные и частые всплески, либо вы получаете меньшую базовую производительность (по той же цене), чтобы иметь возможность позволить себе более крупные и более частые всплески. Это не соответствует профилю веб-скрейпинга, где вам нужны постоянные ЦП и ввод-вывод.

person Ioannis Tsiokos    schedule 10.11.2020

После некоторого тестирования я смог найти удовлетворительное решение:

  1. Переключение экземпляров с t3a.small на t3.small приводит к повышению производительности примерно на 40% и даже на 10-20% быстрее, чем мой домашний ПК. Благодаря @kdgregory
  2. Я улучшил свой код, используя asyncio в сочетании с многопроцессорностью вместо многопоточности. Это не только ускоряет его еще больше, но и приводит к лучшему использованию памяти. Более того, я избавился от тегов, которые все еще существовали после использования bs4.BeautifulSoup (Python high использование памяти с BeautifulSoup). Благодаря последнему улучшению я смог предотвратить увеличение памяти во время работы.
  3. После произвольной программы памяти стало меньше, чем раньше. Я понял, что совершил ошибку новичка: https://www.linuxatemyram.com/ К счастью, это не проблема.

Теперь код работает даже быстрее, чем на моем домашнем ПК, и запускается автоматически.

person MaGarb    schedule 23.07.2019