13

Rozumiem, że możesz wysyłać pojedyncze pliki jako zależności za pomocą programów Python Spark. Ale co z pełnoprawnymi bibliotekami (np. Numpy)?Najłatwiejszy sposób instalacji zależności Pythona na węzłach executorów Spark?

Czy Spark ma sposób na wykorzystanie dostarczonego menedżera pakietów (np. Pip) do zainstalowania zależności bibliotek? Czy też trzeba to zrobić ręcznie przed uruchomieniem programów Spark?

Jeśli odpowiedź jest ręczna, jakie są podejścia "najlepszej praktyki" w zakresie synchronizacji bibliotek (ścieżka instalacji, wersja itp.) W dużej liczbie rozproszonych węzłów?

+2

To irytująco trudne do znalezienia odpowiedzi na to pytanie, ale w końcu znalazłem odpowiedź na to pytanie, które obejmuje to pytanie: http://stackoverflow.com/questions/24686474/shipping-python-modules-in-pyspark- to-other-nodes –

+0

Możliwy duplikat [wysyłki modułów python w pyspark do innych węzłów?] (https://stackoverflow.com/questions/24686474/shipping-python-modules-in-pyspark-to-other-nodes) –

Odpowiedz

11

Właściwie po wypróbowaniu tego, myślę, że link opublikowany jako komentarz nie robi dokładnie tego, co chcesz z zależnościami. To, o co właściwie prosisz, to sposób na przyjemne sparowanie Sparka z setuptools i pip w kwestii instalowania zależności. Dmucha mi w głowie, że to nie jest lepiej obsługiwane w Sparku. Problem zależności od strony trzeciej jest w dużej mierze rozwiązany w Pythonie ogólnego przeznaczenia, ale w Sparku wydaje się, że powinieneś powrócić do ręcznego zarządzania zależnościami.

Używam niedoskonały, ale funkcjonalny rurociąg na podstawie virtualenv. Podstawowym założeniem jest

  1. Tworzenie virtualenv wyłącznie dla węzłów Spark
  2. każdym uruchomieniu zadania Spark, prowadzony świeży pip install wszystkich własnych bibliotek Pythona w domu. Jeśli ustawisz te opcje na setuptools, zainstaluje to zależności. Zapakuj katalog katalogów wirtualnych. Będzie to obejmować swoją bibliotekę i jego zależności, które węzły pracownik będzie potrzebne, ale nie standardowej biblioteki Pythona, które mają już
  3. zdać jeden .zip plik zawierający bibliotek i ich zależności jako argument do --py-files

Oczywiście, chciałbyś zakodować kilka skryptów pomocniczych, aby zarządzać tym procesem. Oto skrypt pomocnik adaptacją jednej używam, które mogłyby zapewne być dużo lepsze:

#!/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 

Mam kolekcję innych prostych skryptów do pakowania biegnę do przedstawienia moich zadań zapłonowe. Po prostu nazywam ten skrypt najpierw jako część tego procesu i upewniam się, że drugi argument (nazwa pliku zip) jest przekazywany jako argument --py-files, kiedy uruchamiam spark-submit (co udokumentowano w komentarzach). Zawsze uruchamiam te skrypty, więc nie kończę przypadkowo uruchomieniem starego kodu. W porównaniu do obciążenia Spark, koszty związane z pakowaniem są minimalne w przypadku mojego projektu na małą skalę.

Istnieje wiele ulepszeń, które można wprowadzić - np. Umiejętność tworzenia nowego pliku zip, dzielenie go na dwa pliki zip, jeden zawierający często zmieniające się pakiety prywatne i zawierający rzadko zmieniające się zależności, co Trzeba tak często przebudowywać. Możesz być mądrzejszy w sprawdzaniu zmian plików przed odbudowaniem zip. Sprawdzanie poprawności argumentów byłoby dobrym pomysłem. Na razie jednak to wystarcza dla moich celów.

Rozwiązanie, które wymyśliłem, nie jest zaprojektowane specjalnie dla dużych zależności takich jak NumPy (chociaż może działać dla nich). Ponadto nie będzie działać, jeśli budujesz rozszerzenia oparte na C, a twój węzeł sterownika ma inną architekturę niż węzły klastra.

Widziałem zaleceń gdzie indziej po prostu uruchomić dystrybucję Python jak Anaconda na wszystkich węzłach, ponieważ zawiera już NumPy (i many other packages), i że może być lepszym sposobem na uzyskanie NumPy jak również inne rozszerzenia C opartych dzieje . Niezależnie od tego, nie zawsze możemy oczekiwać, że Anaconda będzie mieć pakiet PyPI, który chcemy w odpowiedniej wersji, a ponadto możesz nie być w stanie kontrolować swojego środowiska Spark, aby móc umieścić na nim Anaconę, więc myślę, że to oparte na virtualenv podejście jest nadal pomocne.

+3

API w iskrowym kontekście takim jak to: sc.addDependencies ('numpy') jest koniecznością – guilhermecgs

Powiązane problemy