Самый простой способ установить зависимости Python от узлов-исполнителей Spark?

Я понимаю, что вы можете отправлять отдельные файлы в зависимости от программ Python Spark. Но как насчет полноценных библиотек (например, numpy)?

Есть ли у Spark возможность использовать предоставленный менеджер пакетов (например, pip) для установки зависимостей библиотек? Или это нужно сделать вручную до запуска программ Spark?

Если ответ является ручным, то каковы методы «лучшей практики» для синхронизации библиотек (путь установки, версия и т. Д.) На большом количестве распределенных узлов?

    Фактически, фактически попробовав это, я думаю, что ссылка, которую я опубликовал как комментарий, не делает именно то, что вы хотите с зависимостями. То, что вы вполне разумно просите, – это способ, чтобы Spark отлично играли с setuptools и pip относительно установки зависимостей. Мне кажется, что в Спарке это лучше не поддерживается. Проблема зависимостей третьей стороны в значительной степени решена в Python общего назначения, но под Spark кажется предположением, что вы вернетесь к ручному управлению зависимостями или чему-то еще.

    Я использовал несовершенный, но функциональный конвейер, основанный на virtualenv . Основная идея

    1. Создайте виртуальный диск исключительно для ваших узлов Spark
    2. Каждый раз, когда вы запускаете задачу Spark, запускайте новую pip install всех собственных собственных библиотек Python. Если вы установили их с помощью setuptools , это установит их зависимости
    3. Закройте каталог сайтов-пакетов виртуального. Это будет включать в себя вашу библиотеку и ее зависимости, которые потребуются рабочим узлам, но не стандартная библиотека Python, которые у них уже есть.
    4. Передайте один .zip файл, содержащий ваши библиотеки и их зависимости, в качестве аргумента для --py-files

    Конечно, вы захотите составить код вспомогательных скриптов для управления этим процессом. Вот вспомогательный скрипт, адаптированный из того, который я использовал, что, несомненно, могло бы быть улучшено:

     #!/usr/bin/env bash # helper script to fulfil Spark's python packaging requirements. # Installs everything in a designated virtualenv, then zips up the virtualenv for using as an the value of # supplied to --py-files argument of `pyspark` or `spark-submit` # First argument should be the top-level virtualenv # Second argument is the zipfile which will be created, and # which you can subsequently supply as the --py-files argument to # spark-submit # Subsequent arguments are all the private packages you wish to install # If these are set up with setuptools, their dependencies will be installed VENV=$1; shift ZIPFILE=$1; shift PACKAGES=$* . $VENV/bin/activate for pkg in $PACKAGES; do pip install --upgrade $pkg done TMPZIP="$TMPDIR/$RANDOM.zip" # abs path. Use random number to avoid clashes with other processes ( cd "$VENV/lib/python2.7/site-packages" && zip -q -r $TMPZIP . ) mv $TMPZIP $ZIPFILE 

    У меня есть коллекция других простых скриптов-оболочек, которые я запускаю, чтобы отправить свои искровые задания. Я просто вызываю этот скрипт сначала как часть этого процесса и удостоверяюсь, что второй аргумент (имя zip-файла) затем передается как аргумент -py-files при запуске spark-submit (как описано в комментариях). Я всегда запускаю эти сценарии, поэтому я никогда не заканчиваю случайный запуск старого кода. По сравнению с издержками Spark накладные расходы на упаковку минимальны для моего небольшого проекта.

    Есть множество улучшений, которые могут быть сделаны – например, умение создавать новый zip-файл, разделяя его на два zip-файла, один из которых содержит часто меняющиеся частные пакеты, и один, содержащий редко изменяющиеся зависимости, которые не нуждаются в перестраиваться так часто. Вы могли бы умнее проверять изменения файлов перед перестройкой zip. Также правильная проверка правильности аргументов была бы хорошей идеей. Однако на данный момент этого достаточно для моих целей.

    Решение, которое я придумал, специально не предназначено для крупномасштабных зависимостей, таких как NumPy (хотя для них это может работать). Кроме того, это не сработает, если вы создаете расширения на основе C, а ваш узел драйвера имеет другую архитектуру для узлов вашего кластера.

    Я видел рекомендации в других местах, чтобы просто запускать дистрибутив Python, например Anaconda, на всех ваших узлах, поскольку он уже включает NumPy (и многие другие пакеты ), и это может быть лучшим способом получить NumPy, а также другие расширения на основе C. Несмотря на это, мы не всегда можем ожидать, что Anaconda получит пакет PyPI, который мы хотим, в правильной версии, и, кроме того, вы не сможете контролировать свою среду Spark, чтобы иметь возможность установить Anaconda, поэтому я думаю, что этот виртуальный подход по-прежнему полезен.

    Давайте будем гением компьютера.