13

Capisco che è possibile inviare singoli file come dipendenze con i programmi Python Spark. Ma che dire delle librerie a pieno titolo (ad esempio numpy)?Il modo più semplice per installare le dipendenze Python sui nodi executor di Spark?

Spark ha un modo per utilizzare un gestore di pacchetti fornito (ad es. Pip) per installare le dipendenze della libreria? O questo deve essere fatto manualmente prima che i programmi Spark siano eseguiti?

Se la risposta è manuale, quali sono gli approcci di "best practice" per sincronizzare le librerie (percorso di installazione, versione, ecc.) Su un gran numero di nodi distribuiti?

+2

È fastidiosamente difficile trovare una risposta a questa domanda, ma alla fine ho trovato questa risposta alla domanda SO che la riguarda penso: http://stackoverflow.com/questions/24686474/shipping-python-modules-in-pyspark- to-other-nodes –

+0

Possibile duplicato di [spedizione di moduli python in pyspark ad altri nodi?] (https://stackoverflow.com/questions/24686474/shipping-python-modules-in-pyspark-to-other-nodes) –

risposta

11

In realtà, avendo effettivamente provato, penso che il link che ho postato come commento non faccia esattamente quello che vuoi con le dipendenze. Quello che stai ragionevolmente chiedendo è un modo per far sì che Spark giochi bene con setuptools e pip riguardo l'installazione delle dipendenze. Mi viene in mente che questo non è supportato meglio in Spark. Il problema delle dipendenze di terze parti è in gran parte risolto in Python generico, ma sotto Spark sembra che si debba tornare alla gestione delle dipendenze manuali o qualcosa del genere.

Ho utilizzato una pipeline imperfetta ma funzionale basata su virtualenv. L'idea di base è

  1. Creare un virtualenv esclusivamente per i nodi Spark
  2. Ogni volta che si esegue un processo di Spark, eseguire una nuova pip install di tutte le proprie librerie Python in-house. Se li hai configurati con setuptools, verranno installate le loro dipendenze
  3. Zipup la directory dei pacchetti del sito di virtualenv. Ciò comprende la libreria ed è dipendenze, che avranno bisogno i nodi dei lavoratori, ma non la libreria standard di Python, che hanno già
  4. Passare il singolo file .zip, che contiene le librerie e le loro dipendenze come argomento per --py-files

Ovviamente vorrai codificare alcuni script di supporto per gestire questo processo. Ecco uno script di aiuto adattata da quella che ho usato, che potrebbe senz'altro essere migliorato molto:

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

Ho una collezione di altri script wrapper semplici corro a presentare i miei lavori scintilla. Semplicemente chiamo questo script prima come parte di quel processo e mi assicuro che il secondo argomento (nome di un file zip) sia poi passato come argomento --py-files quando corro spark-submit (come documentato nei commenti). Eseguo sempre questi script, quindi non finisco mai per accidentalmente eseguire il vecchio codice. Rispetto all'overhead di Spark, l'overhead della confezione è minimo per il mio progetto su piccola scala.

Ci sono un sacco di miglioramenti che potrebbero essere apportati - ad esempio essere intelligenti su quando creare un nuovo file zip, dividerlo in due file zip, uno contenente pacchetti privati ​​che cambiano spesso e uno contenente dipendenze che cambiano raramente, che don Ho bisogno di essere ricostruito così spesso. Potresti essere più intelligente nel controllare le modifiche ai file prima di ricostruire lo zip. Anche il controllo della validità degli argomenti sarebbe una buona idea. Comunque per ora questo è sufficiente per i miei scopi.

La soluzione che ho trovato non è progettata per dipendenze su larga scala come NumPy in particolare (anche se potrebbe funzionare per loro). Inoltre, non funzionerà se si creano estensioni basate su C e il nodo del driver ha un'architettura diversa rispetto ai nodi del cluster.

ho visto raccomandazioni altrove per eseguire solo una distribuzione di Python come Anaconda su tutti i nodi poiché include già NumPy (e many other packages), e che potrebbe essere il modo migliore per ottenere NumPy così come altre estensioni basate su C in corso . Indipendentemente da ciò, non possiamo sempre aspettarci che Anaconda abbia il pacchetto PyPI che vogliamo nella versione corretta, e inoltre potresti non essere in grado di controllare il tuo ambiente Spark per poterlo inserire su Anaconda, quindi penso che questo sia basato su virtualenv approccio è ancora utile.

+3

un'API in un contesto spark come questo: sc.addDependencies ('numpy') è un must – guilhermecgs

Problemi correlati