wake-up-neo.net

Hinzufügen von Gläsern zu einem Spark-Job

Richtig ... es wurde schon viel diskutiert.

Es gibt jedoch viel Zweideutigkeit und einige der Antworten ... einschließlich des Duplizierens von Jar-Referenzen in der Jars/Executor/Driver-Konfiguration oder in den Optionen.

Die mehrdeutigen und/oder ausgelassenen Details

Nach der Mehrdeutigkeit sollten für jede Option unklare und/oder ausgelassene Details geklärt werden:

  • Auswirkungen auf ClassPath
    • Driver
    • Executor (für laufende Aufgaben)
    • Beide
    • überhaupt nicht
  • Trennzeichen: Komma, Doppelpunkt, Semikolon
  • Wenn bereitgestellte Dateien automatisch verteilt werden
    • für die Aufgaben (für jeden Vollstrecker)
    • für den Remote-Treiber (falls im Cluster-Modus ausgeführt)
  • uRI-Typ akzeptiert: lokale Datei, HDFS, http usw.
  • Wenn in einen allgemeinen Speicherort kopiert, an dem sich dieser Speicherort befindet (hdfs, local?)

Die Optionen, auf die es sich auswirkt:

  1. --jars
  2. SparkContext.addJar(...) -Methode
  3. SparkContext.addFile(...) -Methode 
  4. --conf spark.driver.extraClassPath=... oder --driver-class-path ...
  5. --conf spark.driver.extraLibraryPath=... oder --driver-library-path ...
  6. --conf spark.executor.extraClassPath=...
  7. --conf spark.executor.extraLibraryPath=...
  8. nicht zu vergessen, der letzte parameter des spark-submit ist auch eine .jar-datei.

Mir ist bekannt, wo ich die main spark-Dokumentation finden kann, insbesondere über wie man einreicht, die options verfügbar ist und auch JavaDoc . Das hat mir allerdings noch einige Löcher hinterlassen, obwohl es teilweise auch geantwortet hat.

Ich hoffe, dass es nicht so komplex ist und dass mir jemand eine klare und prägnante Antwort geben kann.

Wenn ich anhand der Dokumentation erraten würde, scheinen die Methoden --jars und SparkContextaddJar und addFile die Dateien automatisch zu verteilen, während die anderen Optionen lediglich den ClassPath ändern.

Ist es sicher, anzunehmen, dass ich der Einfachheit halber zusätzliche Anwendungs-JAR-Dateien hinzufügen kann, indem Sie die 3 Hauptoptionen gleichzeitig verwenden:

spark-submit --jar additional1.jar,additional2.jar \
  --driver-library-path additional1.jar:additional2.jar \
  --conf spark.executor.extraLibraryPath=additional1.jar:additional2.jar \
  --class MyClass main-application.jar

Nizza-Artikel zu eine Antwort auf ein anderes Posting gefunden. Allerdings nichts Neues gelernt. Das Poster macht eine gute Bemerkung zum Unterschied zwischen lokalem Treiber (Garn-Client) und Remote-Treiber (Garn-Cluster). Definitiv wichtig zu beachten.

117
YoYo

Klassenpfad:

ClassPath ist davon abhängig, was Sie bereitstellen. Es gibt verschiedene Möglichkeiten, etwas auf dem Klassenpfad festzulegen:

  • spark.driver.extraClassPath oder sein Alias ​​--driver-class-path, um zusätzliche Klassenpfade auf dem Knoten festzulegen, auf dem der Treiber ausgeführt wird.
  • spark.executor.extraClassPath, um einen zusätzlichen Klassenpfad auf den Worker-Knoten festzulegen.

Wenn Sie möchten, dass ein bestimmter JAR sowohl auf dem Master als auch auf dem Worker ausgeführt wird, müssen Sie diese in BEIDEN Flags separat angeben.

Trennzeichen:

Nach den gleichen Regeln wie die JVM :

  • Linux: Ein Doppelpunkt :
    • beispiel: --conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar:/opt/prog/aws-Java-sdk-1.10.50.jar"
  • Windows: Ein Semikolon ;
    • beispiel: --conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar;/opt/prog/aws-Java-sdk-1.10.50.jar"

Dateiverteilung:

Dies hängt davon ab, in welchem ​​Modus Sie Ihren Job ausführen:

  1. Client-Modus - Spark startet einen Netty HTTP-Server, der die Dateien beim Start für jeden Arbeiterknoten verteilt. Sie können das sehen, wenn Sie Ihren Spark-Job starten:

    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
    
  2. Cluster-Modus - Im Cluster-Modus hat spark einen führenden Worker-Knoten ausgewählt, auf dem der Treiberprozess ausgeführt werden soll. Dies bedeutet, dass der Job nicht direkt vom Master-Knoten ausgeführt wird. Hier setzt Spark keinen HTTP-Server. Sie müssen Ihre JARS manuell für alle Arbeiterknoten über HDFS/S3/Andere Quellen verfügbar machen, die allen Knoten zur Verfügung stehen.

Akzeptierte URIs für Dateien

In "Einreichen von Anträgen" erklärt die Spark-Dokumentation die akzeptierten Präfixe für Dateien.

Bei der Verwendung von spark-submit wird die Anwendung zusammen mit allen anderen Dosen jas- siert in der Option --jars enthalten ist, wird automatisch an .__ übergeben. der Cluster Spark verwendet das folgende URL-Schema, um unterschiedliche Strategien zur Verbreitung von Gläsern:

  • file: - Absolute Pfade und file:/URIs werden vom HTTP .__ des Treibers bereitgestellt. Dateiserver, und jeder Executor holt die Datei aus dem Treiber HTTP Server. 
  • hdfs :, http :, https :, ftp: - Diese Dateien und JARs ziehen diese Dateien herunter von der URI wie erwartet 
  • local: - Ein URI, der mit local:/beginnt, ist voraussichtlich als lokale Datei auf jedem Arbeitsknoten vorhanden sein. Das bedeutet, dass Es entsteht kein Netzwerk IO, das für große Dateien/JARs gut geeignet ist die an jeden Mitarbeiter weitergeleitet werden oder über NFS, GlusterFS usw. gemeinsam genutzt werden.

Beachten Sie, dass JARs und Dateien für jedes .__ in das Arbeitsverzeichnis kopiert werden. SparkContext auf den Executor-Knoten.

Wie bereits erwähnt, werden JARs für jeden Worker-Knoten in das Arbeitsverzeichnis kopiert. Wo genau ist das Es ist normalerweise unter /var/run/spark/work, Sie werden sie wie folgt sehen:

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

Wenn Sie nach innen schauen, sehen Sie alle von Ihnen bereitgestellten JARs:

[*@*]$ 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

Betroffene Optionen:

Das wichtigste zu verstehen ist Priorität. Wenn Sie eine Eigenschaft per Code übergeben, hat sie Vorrang vor allen Optionen, die Sie über spark-submit angeben. Dies wird in der Spark-Dokumentation erwähnt:

Alle als Flags oder in der Eigenschaftendatei angegebenen Werte werden .__ übergeben. auf die Anwendung und mit den durch SparkConf. Eigenschaften, die direkt auf der SparkConf eingestellt sind, nehmen den höchsten Wert Vorrang, dann Flags an spark-submit oder spark-Shell übergeben, dann Optionen in der Datei spark-defaults.conf

Stellen Sie also sicher, dass Sie diese Werte an den richtigen Stellen festlegen, damit Sie nicht überrascht sind, wenn einer der anderen Vorrang hat.

Lassen Sie uns jede fragliche Option analysieren:

  • --jars vs SparkContext.addJar: Diese sind identisch, es wird nur eine über Spark Submit und eine über Code gesetzt. Wählen Sie diejenige aus, die Ihnen besser entspricht. Es ist wichtig zu beachten, dass bei Verwendung dieser Optionen die JAR nicht zu Ihrem driver/executor-Klassenpfad hinzugefügt wird, müssen Sie sie explizit hinzufügen, indem Sie die extraClassPath config für beide verwenden.
  • SparkContext.addJar vs SparkContext.addFile: Verwenden Sie die erste Option, wenn Sie eine Abhängigkeit haben, die mit Ihrem Code verwendet werden muss. Verwenden Sie Letzteres, wenn Sie einfach eine beliebige Datei an Ihre Arbeitsknoten weitergeben möchten. Dies ist keine Laufzeitabhängigkeit im Code.
  • --conf spark.driver.extraClassPath=... oder --driver-class-path: Hierbei handelt es sich um Aliase, unabhängig davon, welchen Sie wählen
  • --conf spark.driver.extraLibraryPath=..., or --driver-library-path ... Gleich wie oben, Aliase.
  • --conf spark.executor.extraClassPath=...: Verwenden Sie diese Option, wenn Sie eine Abhängigkeit haben, die nicht in eine übergeordnete JAR-Datei eingeschlossen werden kann (z. B. weil Kompilierzeitkonflikte zwischen Bibliotheksversionen bestehen) und die Sie zur Laufzeit laden müssen.
  • --conf spark.executor.extraLibraryPath=... Dies wird als Java.library.path-Option für die JVM übergeben. Verwenden Sie dies, wenn Sie einen Bibliothekspfad benötigen, der für die JVM sichtbar ist.

Könnte man davon ausgehen, dass ich der Einfachheit halber zusätzliche .__ hinzufügen kann. Anwendungs-JAR-Dateien mit den drei Hauptoptionen gleichzeitig:

Sie können dies nur für den Client-Modus und nicht für den Cluster-Modus annehmen. Wie ich schon gesagt habe. Das Beispiel, das Sie gegeben haben, enthält einige redundante Argumente. Das Übergeben von JARs an --driver-library-path ist beispielsweise nutzlos. Sie müssen sie an extraClassPath übergeben, wenn Sie möchten, dass sie sich in Ihrem Klassenpfad befinden. Letztendlich möchten Sie bei der Bereitstellung externer JARs sowohl auf dem Treiber als auch auf dem Worker Folgendes tun:

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
126
Yuval Itzchakov

Ein anderer Ansatz in spark 2.1.0 ist die Verwendung von --conf spark.driver.userClassPathFirst=true während Spark-Submit, wodurch die Priorität der Abhängigkeitslast und somit das Verhalten des Spark-Jobs geändert wird, indem denjenigen Gliedern Priorität gegeben wird, die der Benutzer mit der Option --jars dem Klassenpfad hinzufügt.

3
Stanislav

Andere konfigurierbare Spark -Optionen in Bezug auf JARS und Classpath im Fall von yarn als Bereitstellungsmodus lauten wie folgt
Aus der spark Dokumentation,

spark.yarn.jars

Liste der Bibliotheken mit Spark Code, die an YARN-Container verteilt werden sollen. Standardmäßig werden für Spark in YARN Spark Jars verwendet, die lokal installiert sind. Die Spark Jars können sich jedoch auch an einem weltweit lesbaren Speicherort in HDFS befinden. Auf diese Weise kann YARN es auf Knoten zwischenspeichern, sodass es nicht jedes Mal verteilt werden muss, wenn eine Anwendung ausgeführt wird. Um beispielsweise auf JARs in HDFS zu verweisen, setzen Sie diese Konfiguration auf hdfs: /// some/path. Globs sind erlaubt.

spark.yarn.archive

Ein Archiv, das die für die Verteilung an den YARN-Cache benötigten Spark Jars enthält. Wenn festgelegt, ersetzt diese Konfiguration spark.yarn.jars und das Archiv wird in allen Containern der Anwendung verwendet. Das Archiv sollte im Stammverzeichnis JAR-Dateien enthalten. Wie bei der vorherigen Option kann das Archiv auch auf HDFS gehostet werden, um die Dateiverteilung zu beschleunigen.

Benutzer können diesen Parameter so konfigurieren, dass er ihre Jars angibt, die im Klassenpfad des Treibers Spark enthalten sind.

1
DaRkMaN

Während wir Spark-Jobs mit dem Dienstprogramm spark-submit übergeben, gibt es eine Option --jars. Mit dieser Option können wir JAR-Dateien an Spark-Anwendungen übergeben.

0
bala

Es gibt eine Einschränkung bei der Verwendung von --jars: Wenn Sie ein Verzeichnis für den Ort der jar/xml-Datei angeben möchten, sind Verzeichniserweiterungen nicht zulässig. Dies bedeutet, wenn Sie für jedes Glas einen absoluten Pfad angeben müssen.

Wenn Sie --driver-class-path angeben und im Garncluster-Modus ausgeführt werden, wird die Treiberklasse nicht aktualisiert. Wir können überprüfen, ob der Klassenpfad unter spark ui oder der spark history Server in der Tab-Umgebung aktualisiert wird.

Option, die für mich funktionierte, um Gläser zu übergeben, die Verzeichniserweiterungen enthalten und die im Garncluster-Modus arbeiten, war --conf-Option. Es ist besser, Treiber- und Executor-Klassenpfade als --conf zu übergeben, wodurch sie zum Funksitzungsobjekt selbst hinzugefügt werden. Diese Pfade werden in der Spark-Konfiguration angezeigt. Stellen Sie jedoch sicher, dass sich Gläser auf demselben Pfad im Cluster befinden.

spark-submit \
  --master yarn \
  --queue spark_queue \
  --deploy-mode cluster    \
  --num-executors 12 \
  --executor-memory 4g \
  --driver-memory 8g \
  --executor-cores 4 \
  --conf spark.ui.enabled=False \
  --conf spark.driver.extraClassPath=/usr/hdp/current/hbase-master/lib/hbase-server.jar:/usr/hdp/current/hbase-master/lib/hbase-common.jar:/usr/hdp/current/hbase-master/lib/hbase-client.jar:/usr/hdp/current/hbase-master/lib/zookeeper.jar:/usr/hdp/current/hbase-master/lib/hbase-protocol.jar:/usr/hdp/current/spark2-thriftserver/examples/jars/scopt_2.11-3.3.0.jar:/usr/hdp/current/spark2-thriftserver/examples/jars/spark-examples_2.10-1.1.0.jar:/etc/hbase/conf \
  --conf spark.hadoop.mapred.output.dir=/tmp \
  --conf spark.executor.extraClassPath=/usr/hdp/current/hbase-master/lib/hbase-server.jar:/usr/hdp/current/hbase-master/lib/hbase-common.jar:/usr/hdp/current/hbase-master/lib/hbase-client.jar:/usr/hdp/current/hbase-master/lib/zookeeper.jar:/usr/hdp/current/hbase-master/lib/hbase-protocol.jar:/usr/hdp/current/spark2-thriftserver/examples/jars/scopt_2.11-3.3.0.jar:/usr/hdp/current/spark2-thriftserver/examples/jars/spark-examples_2.10-1.1.0.jar:/etc/hbase/conf \
  --conf spark.hadoop.mapreduce.output.fileoutputformat.outputdir=/tmp
0
Tanveer