ClassPath:
ClassPath è interessato a seconda di ciò che fornisci. Ci sono un paio di modi per impostare qualcosa sul percorso di classe:
spark.driver.extraClassPath
oppure è alias --driver-class-path
impostare percorsi di classe extra sul nodo che esegue il driver.
spark.executor.extraClassPath
per impostare un percorso di classe extra sui nodi Worker.
Se si desidera effettuare un determinato JAR sia sul Master che sul Worker, è necessario specificarli separatamente in ENTRAMBI i flag.
Carattere di separazione:
Seguendo le stesse regole della JVM :
- Linux: i due punti
:
- per esempio:
--conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar:/opt/prog/aws-java-sdk-1.10.50.jar"
- Windows: un punto e virgola
;
- per esempio:
--conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar;/opt/prog/aws-java-sdk-1.10.50.jar"
Distribuzione dei file:
Questo dipende dalla modalità in cui stai eseguendo il tuo lavoro:
Modalità client: Spark avvia un server HTTP Netty che distribuisce i file all'avvio per ciascuno dei nodi di lavoro. Puoi vederlo quando avvii il tuo lavoro Spark:
16/05/08 17:29:12 INFO HttpFileServer: HTTP File server directory is /tmp/spark-48911afa-db63-4ffc-a298-015e8b96bc55/httpd-84ae312b-5863-4f4c-a1ea-537bfca2bc2b
16/05/08 17:29:12 INFO HttpServer: Starting HTTP Server
16/05/08 17:29:12 INFO Utils: Successfully started service 'HTTP file server' on port 58922.
16/05/08 17:29:12 INFO SparkContext: Added JAR /opt/foo.jar at http://***:58922/jars/com.mycode.jar with timestamp 1462728552732
16/05/08 17:29:12 INFO SparkContext: Added JAR /opt/aws-java-sdk-1.10.50.jar at http://***:58922/jars/aws-java-sdk-1.10.50.jar with timestamp 1462728552767
Modalità cluster: in modalità cluster spark ha selezionato un nodo Worker leader su cui eseguire il processo Driver. Ciò significa che il lavoro non è in esecuzione direttamente dal nodo principale. Qui, Spark non imposterà un server HTTP. Devi rendere manualmente i tuoi JARS disponibili a tutto il nodo di lavoro tramite HDFS / S3 / Altre fonti che sono disponibili per tutti i nodi.
URI accettati per i file
In "Invio di applicazioni" , la documentazione Spark fa un buon lavoro nel spiegare i prefissi accettati per i file:
Quando si utilizza spark-submit, il vaso dell'applicazione insieme a tutti i vasetti inclusi con l'opzione --jars verranno automaticamente trasferiti al cluster. Spark utilizza il seguente schema URL per consentire diverse strategie per la diffusione di vasetti:
- file: - Percorsi assoluti e file: / URI sono serviti dal file server HTTP del driver e ogni esecutore estrae il file dal server HTTP del driver.
- hdfs :, http :, https :, ftp: - questi pull down file e JAR dall'URI come previsto
- local: - un URI che inizia con local: / dovrebbe esistere come file locale su ciascun nodo di lavoro. Ciò significa che non si verificherà alcun IO di rete e funziona bene per file / JAR di grandi dimensioni che vengono inviati a ciascun lavoratore o condivisi tramite NFS, GlusterFS, ecc.
Notare che JAR e file vengono copiati nella directory di lavoro per ogni SparkContext sui nodi dell'esecutore.
Come notato, i JAR vengono copiati nella directory di lavoro per ciascun nodo di lavoro. Dov'è esattamente quello? Di solito è sotto /var/run/spark/work
, li vedrai così:
drwxr-xr-x 3 spark spark 4096 May 15 06:16 app-20160515061614-0027
drwxr-xr-x 3 spark spark 4096 May 15 07:04 app-20160515070442-0028
drwxr-xr-x 3 spark spark 4096 May 15 07:18 app-20160515071819-0029
drwxr-xr-x 3 spark spark 4096 May 15 07:38 app-20160515073852-0030
drwxr-xr-x 3 spark spark 4096 May 15 08:13 app-20160515081350-0031
drwxr-xr-x 3 spark spark 4096 May 18 17:20 app-20160518172020-0032
drwxr-xr-x 3 spark spark 4096 May 18 17:20 app-20160518172045-0033
E quando guardi dentro, vedrai tutti i JAR che hai schierato lungo:
[*@*]$ cd /var/run/spark/work/app-20160508173423-0014/1/
[*@*]$ ll
total 89988
-rwxr-xr-x 1 spark spark 801117 May 8 17:34 awscala_2.10-0.5.5.jar
-rwxr-xr-x 1 spark spark 29558264 May 8 17:34 aws-java-sdk-1.10.50.jar
-rwxr-xr-x 1 spark spark 59466931 May 8 17:34 com.mycode.code.jar
-rwxr-xr-x 1 spark spark 2308517 May 8 17:34 guava-19.0.jar
-rw-r--r-- 1 spark spark 457 May 8 17:34 stderr
-rw-r--r-- 1 spark spark 0 May 8 17:34 stdout
Opzioni interessate:
La cosa più importante da capire è la priorità . Se si passa una proprietà tramite il codice, avrà la precedenza su qualsiasi opzione specificata tramite spark-submit
. Questo è menzionato nella documentazione Spark:
Tutti i valori specificati come flag o nel file delle proprietà verranno passati all'applicazione e uniti a quelli specificati tramite SparkConf. Le proprietà impostate direttamente su SparkConf hanno la massima priorità , quindi i flag passati a spark-submit o spark-shell, quindi le opzioni nel file spark-defaults.conf
Quindi assicurati di impostare quei valori nei posti giusti, in modo da non essere sorpreso quando uno ha la priorità sull'altro.
Analizziamo ogni opzione in questione:
--jars
vs SparkContext.addJar
: sono identici, solo uno è impostato tramite spark submit e uno tramite codice. Scegli quello che ti piace di più. Una cosa importante da notare è che l'utilizzo di una di queste opzioni non aggiunge il JAR al percorso di classe del tuo driver / esecutore , dovrai aggiungerli esplicitamente usando la extraClassPath
configurazione su entrambi.
SparkContext.addJar
vs SparkContext.addFile
: usa il primo quando hai una dipendenza che deve essere usata con il tuo codice. Utilizzare quest'ultimo quando si desidera semplicemente passare un file arbitrario ai nodi di lavoro, che non è una dipendenza runtime nel codice.
--conf spark.driver.extraClassPath=...
oppure --driver-class-path
: questi sono alias, non importa quale scegli
--conf spark.driver.extraLibraryPath=..., or --driver-library-path ...
Come sopra, alias.
--conf spark.executor.extraClassPath=...
: Utilizzare questa opzione quando si ha una dipendenza che non può essere inclusa in un JAR superar (ad esempio perché ci sono conflitti di tempo di compilazione tra le versioni della libreria) e che è necessario caricare in fase di esecuzione.
--conf spark.executor.extraLibraryPath=...
Questo è passato come java.library.path
opzione per la JVM. Usalo quando hai bisogno di un percorso di libreria visibile alla JVM.
Sarebbe sicuro supporre che, per semplicità, posso aggiungere ulteriori file jar dell'applicazione usando contemporaneamente le 3 opzioni principali:
Puoi assumerlo in sicurezza solo per la modalità Client, non per la modalità Cluster. Come ho già detto. Inoltre, l'esempio che hai fornito ha alcuni argomenti ridondanti. Ad esempio, passare i JAR a --driver-library-path
è inutile, è necessario passarli a extraClassPath
se si desidera che siano sul tuo percorso di classe. In definitiva, ciò che si desidera fare quando si distribuiscono JAR esterni sia sul driver che sul lavoratore è:
spark-submit --jars additional1.jar,additional2.jar \
--driver-class-path additional1.jar:additional2.jar \
--conf spark.executor.extraClassPath=additional1.jar:additional2.jar \
--class MyClass main-application.jar