Подтвердить что ты не робот

Параллельная установка

Наш проект Django становится огромным. У нас есть сотни приложений и использование тонны сторонних пакетов python, многие из которых требуют компиляции C. Наши развертывания занимают много времени, когда нам нужно создать новую виртуальную среду для основных выпусков. С учетом сказанного, я хочу ускорить процесс, начиная с Пипа. Кто-нибудь знает о вилке Pip, которая будет устанавливать пакеты параллельно?

Шаги, которые я сделал до сих пор:

  • Я искал проект, который делает это с небольшим успехом. Я нашел этот Github Gist: https://gist.github.com/1971720, но результаты почти точно такие же, как у нашего однопоточного друга.

  • Затем я нашел проект Pip на Github и начал просматривать сеть вилок, чтобы узнать, могу ли я найти какие-либо коммиты, которые упомянули о том, что я делаю. Там беспорядок. Я буду раскошелиться и попытаться распараллелить его сам, если придется, я просто хочу избежать траты времени на это.

  • Я видел разговор в DjangoCon 2011 от ep.io, объясняющий их материал для развертывания, и они упоминают распараллеливание писем, отправка файлов .so вместо компиляции C и зеркалирование Pypi, но они не касались того, как они это сделали или что они использовали.

4b9b3361

Ответ 1

Проанализировали ли вы процесс развертывания, чтобы узнать, где действительно идет время? Меня удивляет, что запуск нескольких параллельных процессов pip не ускоряет его.

Если пришло время запросить PyPI и найти пакеты (в частности, когда вы также загружаете из Github и других источников), может быть полезно настроить собственный PyPI. Вы можете разместить PyPI самостоятельно и добавить следующее в свой requirements.txt файл (docs):

--extra-index-url YOUR_URL_HERE

или ниже, если вы хотите заменить официальный PyPI в целом:

--index-url YOUR_URL_HERE

Это может ускорить время загрузки, так как все пакеты теперь находятся на ближайшей машине.

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

Ответ 2

Основываясь на ответе Джеймисона Беккера, следующий код выполняет параллельную загрузку Пика, а затем быстро устанавливает пакеты.

Сначала мы загружаем пакеты параллельно в каталог (dist). Это легко запускается параллельно без конфликтов. Каждое отпечатанное имя пакета распечатывается перед загрузкой, что помогает при отладке. Для получения дополнительной помощи измените -P9 на -P1, чтобы загрузить последовательно.

После загрузки следующая команда сообщает Pip об установке и обновлении пакетов. Файлы не загружаются, они извлекаются из быстрого локального каталога.

Он совместим с текущей версией Pip 1.7, также с Pip 1.5.

Чтобы установить только подмножество пакетов, замените оператор `cat require.txt 'своей пользовательской командой, например. 'egrep -v github require.txt'

cat requirements.txt | xargs -t -n1 -P9 pip install -q --download ./dist

pip install --no-index --find-links=./dist -r ./requirements.txt

Ответ 3

Установка параллельного соединения

В этом примере используется xargs, чтобы распараллелить процесс сборки примерно на 4 раза. Вы можете увеличить коэффициент параллелизации с max-procs ниже (держите его приблизительно равным количеству ваших ядер).

Если вы пытаетесь, например, ускорить процесс обработки изображений, который вы делаете снова и снова, может быть проще и определенно снизить потребление полосы пропускания, чтобы просто изображать непосредственно результат, а не делать это каждый раз, или создавать изображение с помощью pip -t или virtualenv.

Загружать и устанавливать пакеты параллельно, по четыре за раз:

xargs --max-args=1 --max-procs=4 sudo pip install < requires.txt

Примечание. xargs имеет разные имена параметров в разных дистрибутивах Linux. Проверьте спецификацию своей страницы рассылки.

То же самое, что указано в здесь-doc:

 cat << EOF | xargs --max-args=1 --max-procs=4 sudo pip install
 awscli
 bottle
 paste
 boto                                                                         
 wheel
 twine                                                                        
 markdown
 python-slugify
 python-bcrypt
 arrow
 redis
 psutil
 requests
 requests-aws
 EOF

Предупреждение: существует вероятность того, что скорость этого метода может сбить содержимое пакетов (в зависимости от вашего дистрибутива), если несколько пипов попытаются установить одну и ту же зависимость в одно и то же время, но это очень маловероятно, если вы только делая 4 за раз. Это можно легко устранить с помощью pip install --uninstall depname.

Ответ 4

Будет ли это помогать, если у вас есть ваша система сборки (например, Дженкинс), сборка и установка всего в каталог виртуальной среды для конкретной сборки? Когда сборка завершается успешно, вы делаете виртуальную среду перемещаемой, архивируете ее и выталкиваете полученный tablall в хранилище "выпущенных архивов". Во время развертывания вам нужно взять последний архив и распаковать его на целевом хосте, а затем он должен быть готов к выполнению. Так что, если загрузка файла tarball занимает 2 секунды, а на место назначения - 0,5 секунды, ваше развертывание займет 2,5 секунды.

Преимущество такого подхода заключается в том, что все установки пакетов происходят во время сборки, а не во время развертывания.

Предостережение: ваш сотрудник системы сборки, который строит/компилирует/устанавливает вещи в виртуальный env, должен использовать ту же архитектуру, что и целевое оборудование. Кроме того, ваша система подготовки к производству продуктов должна будет заботиться о различных зависимостях библиотеки C, которые могут иметь некоторые пакеты Python (например, PIL требует, чтобы libjpeg был установлен до того, как он сможет скомпилировать код, связанный с JPEG, также ситуация сломается, если libjpeg не установлен в целевом поле)

Это хорошо работает для нас.

Создание виртуального env relocatable:

virtualenv --relocatable /build/output/dir/build-1123423

В этом примере build-1123423 представляет собой виртуальный каталог env для сборки.

Ответ 5

Вдохновленный Ответ Jamieson Becker, я изменил установку script, чтобы выполнить параллельные установки папок, и это похоже на улучшение. Мой bash script теперь содержит фрагмент, подобный этому:

requirements=''\
'numpy '\
'scipy '\
'Pillow '\
'feedgenerator '\
'jinja2 '\
'docutils '\
'argparse '\
'pygments '\
'Typogrify '\
'Markdown '\
'jsonschema '\
'pyzmq '\
'terminado '\
'pandas '\
'spyder '\
'matplotlib '\
'statlab '\
'ipython[all]>=3 '\
'ipdb '\
''tornado>=4' '\
'simplepam '\
'sqlalchemy '\
'requests '\
'Flask '\
'autopep8 '\
'python-dateutil '\
'pylibmc '\
'newrelic '\
'markdown '\
'elasticsearch '\
"'"'docker-py==1.1.0'"'"' '\
"'"'pycurl==7.19.5'"'"' '\
"'"'futures==2.2.0'"'"' '\
"'"'pytz==2014.7'"'"' '

echo requirements=${requirements}
for i in ${requirements}; do ( pip install $i > /tmp/$i.out 2>&1 & ); done

Я могу хотя бы искать проблемы вручную.