jarをSparkジョブに追加する-spark-submit


158

確かに...それはかなり議論されてきました。

ただし、あいまいさが多く、いくつかの回答が提供されています。jars/ executor / driver構成またはオプションでのjar参照の複製を含みます。

あいまいまたは省略された詳細

次のあいまいさに従って、不明確な、および/または省略された詳細は、各オプションについて明確にされるべきです:

  • ClassPathへの影響
    • 運転者
    • エグゼキューター(実行中のタスク用)
    • 両方とも
    • どういたしまして
  • 区切り文字:コンマ、コロン、セミコロン
  • 提供されたファイルが自動的に配布される場合
    • タスク(各エグゼキューターへ)
    • リモートドライバー用(クラスターモードで実行した場合)
  • 受け入れられるURIのタイプ:ローカルファイル、hdfs、httpなど
  • 共通の場所にコピーた場合、その場所は(hdfs、local?)

影響を受けるオプション:

  1. --jars
  2. SparkContext.addJar(...) 方法
  3. SparkContext.addFile(...) 方法
  4. --conf spark.driver.extraClassPath=... または --driver-class-path ...
  5. --conf spark.driver.extraLibraryPath=...、または --driver-library-path ...
  6. --conf spark.executor.extraClassPath=...
  7. --conf spark.executor.extraLibraryPath=...
  8. 忘れないでください。spark-submitの最後のパラメーターも.jarファイルです。

メインのSparkドキュメントがどこにあるか、具体的には送信方法使用可能なオプション、およびJavaDocについて知っています。しかし、それでも部分的には答えましたが、まだかなりの穴が残っています。

それほど複雑ではなく、誰かが私に明確で簡潔な答えを出してくれることを願っています。

ドキュメントから推測する--jarsと、SparkContext addJaraddFileメソッドはファイルを自動的に配布するものであり、他のオプションはClassPathを変更するだけです。

簡単にするために、3つの主要なオプションを同時に使用して追加のアプリケーションjarファイルを追加できると想定しても安全でしょうか。

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

別の投稿への回答に関する素晴らしい記事を見つけました。しかし、新しいことは何も学びませんでした。ポスターは、ローカルドライバー(yarn-client)とリモートドライバー(yarn-cluster)の違いについてよく述べています。心に留めておくことが絶対に重要です。


1
どのクラスターマネージャーを実行していますか?スタンドアロン/ YARN / Mesos?
ユヴァルイチャコフ2016年

どれか。これは元のドキュメントを明確にするためのものです。私は主にスタンドアロンクラスター、単一インスタンス、yarn-client、yarn-clusterを使用しています。他のユーザーはMesosを使用している可能性があります。あなたはこれに関してあなたのブログでいくつかの良いオリジナルの研究をしたようです。シェーダーを使用してUber jarを作成し、展開プロセスを簡略化しました。
ヨーヨー、2016年

1
Spark Standaloneの展開方法に関する回答を投稿します。
ユヴァルイチャコフ2016年

6
私はあなたのすべての質問に答える努力をしました。それがお役に立て
ば幸い

@Yuval Itzchakov、ちょうどYoyoが述べたように、私もすべての依存関係(例:ケースクラス)と私が使用している可能性のある他のjarをバンドルするために色付きのjarを使用します。複数のjarファイルが必要な状況にいつ遭遇するかを理解しようとしています。つまり、これらの複数のjarファイルを常に1つのuber jarファイルにバンドルできます。シェーディングされたjarをすべての依存関係にバンドルして、引き続き使用できないのはなぜですか?
Sheel Pancholi

回答:


177

クラスパス:

ClassPathは、提供する内容に応じて影響を受けます。クラスパスに何かを設定するには、いくつかの方法があります。

  • spark.driver.extraClassPathまたは--driver-class-path、ドライバを実行しているノードに追加のクラスパスを設定するエイリアスです。
  • spark.executor.extraClassPath ワーカーノードに追加のクラスパスを設定する。

特定のJARをマスターとワーカーの両方で有効にする場合は、両方のフラグでこれらを個別に指定する必要があります。

分離文字:

JVMと同じルールに従う

  • Linux:コロン :
    • 例えば: --conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar:/opt/prog/aws-java-sdk-1.10.50.jar"
  • Windows:セミコロン ;
    • 例えば: --conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar;/opt/prog/aws-java-sdk-1.10.50.jar"

ファイル配布:

これは、ジョブを実行しているモードによって異なります。

  1. クライアントモード-Sparkは、各ワーカーノードの起動時にファイルを配布するNetty HTTPサーバーを起動します。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
  2. クラスターモード-クラスターモードのSparkでは、リーダープロセスを実行するリーダーワーカーノードが選択されています。これは、ジョブがマスターノードから直接実行されていないことを意味します。ここでは、Spark HTTPサーバーを設定しません。すべてのノードで使用できるHDFS / S3 / Otherソースを介して、すべてのワーカーノードでJARSを手動で使用できるようにする必要があります。

ファイルの受け入れられるURI

では「提出アプリケーション」、スパークのドキュメントは、ファイルのための受け入れられたプレフィックスを説明するのは良い仕事をしていません。

spark-submitを使用すると、アプリケーションのjarと--jarsオプションに含まれているjarが自動的にクラスターに転送されます。Sparkは次のURLスキームを使用して、jarを配布するためのさまざまな戦略を可能にします。

  • file:-絶対パスとfile:/ URIは、ドライバーのHTTPファイルサーバーによって提供され、すべてのエグゼキューターがドライバーのHTTPサーバーからファイルをプルします。
  • hdfs:、http:、https:、ftp:-これらは期待どおりにURIからファイルとJARをプルダウンします
  • local:-local:/で始まるURIは、各ワーカーノードのローカルファイルとして存在することが想定されています。これは、ネットワークIOが発生せず、各ワーカーにプッシュされる、またはNFS、GlusterFSなどを介して共有される大きなファイル/ JARに対して適切に機能することを意味します。

JARとファイルは、executorノード上の各SparkContextの作業ディレクトリーにコピーされることに注意してください。

前述のように、JARは各ワーカーノードの作業ディレクトリにコピーされます。それは正確にはどこですか?それは通常の下で/var/run/spark/work、あなたはこのようにそれらが表示されます:

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

内部を見ると、デプロイしたすべてのJARが表示されます。

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

影響を受けるオプション:

理解する最も重要なことは優先順位です。コードを介してプロパティを渡した場合、それは、を介して指定したオプションよりも優先されますspark-submit。これはSparkのドキュメントで言及されています:

フラグまたはプロパティファイルで指定された値はすべてアプリケーションに渡され、SparkConfで指定された値とマージされます。SparkConfに直接設定されたプロパティが最も優先され、spark-submitまたはspark-shellに渡されたフラグ、spark-defaults.confファイルのオプション

したがって、これらの値を適切な場所に設定してください。そうすることで、一方が他方よりも優先されても驚かないでしょう。

問題の各オプションを分析しましょう:

  • --jarsvs SparkContext.addJar:これらは同じです。sparksubmitを介して設定されるのは1つだけで、コードを介して設定されるのは1つだけです。あなたに合ったものを選んでください。注意すべき重要な点の1つは、これらのオプションのどちらを使用しても、JARがドライバー/エグゼキューターのクラスパスに追加されないためextraClassPath、両方の構成を使用して明示的に追加する必要があるということです。
  • SparkContext.addJarvs SparkContext.addFile:コードで使用する必要がある依存関係がある場合は、前者を使用します。後者は、任意のファイルをワーカーノードに渡したいだけの場合に使用します。これは、コードの実行時の依存関係ではありません。
  • --conf spark.driver.extraClassPath=...または--driver-class-path:これらはエイリアスです。どちらを選択してもかまいません。
  • --conf spark.driver.extraLibraryPath=..., or --driver-library-path ... 上記と同じ、エイリアス。
  • --conf spark.executor.extraClassPath=...:これは、uber JARに含めることができない依存関係(たとえば、ライブラリのバージョン間にコンパイル時の競合があるため)があり、実行時にロードする必要がある場合に使用します。
  • --conf spark.executor.extraLibraryPath=...これはjava.library.path、JVM のオプションとして渡されます。これは、JVMから見えるライブラリパスが必要な場合に使用します。

簡単にするために、3つの主要なオプションを同時に使用して追加のアプリケーションjarファイルを追加できると想定しても安全でしょうか。

これは、クラスターモードではなく、クライアントモードでのみ安全に想定できます。以前に言ったように。また、あなたが与えた例にはいくつかの冗長な引数があります。たとえば、JARを渡しても意味がありません。JARをクラスパスに置きたい場合--driver-library-pathは、JARを渡す必要がありextraClassPathます。最終的に、ドライバーとワーカーの両方に外部JARをデプロイするときに行うことは次のとおりです。

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

4
素晴らしい包括的な答え。ありがとうございました。あなたもと展開のベストプラクティスについて詳しく教えてもらえユーバーJAR依存関係外のJAR(外部フォルダのLIBSとに記載されているMANIFEST.MFファイル)?
jsosnowski

2
@jsosnowski通常、私はuber JARで解決するのが非常に複雑な競合がある場合にのみ、外部jarの使用を採用します。私は通常、SBT assemblyMergeStrategyを使用し、競合がある場合に必要なクラスを選択するだけで問題を解決します。私は一般的に同じことをお勧めします。
Yuval Itzchakov 16

9
@ yuval-itzchakov素晴らしい回答をありがとう、とても役に立ちました。私がしたのと同じ過ちをしたかもしれない他の人を助けるために強調したい1つのポイント。--jars引数は、jarをクラスター内の各マシンにのみ転送します。クラスパス検索でそれらを使用するようにSparkに指示しません。--driver-class-path(または同様の引数または構成パラメーター)も必要です。最初は同じことをする別の方法だと思っていました。
Tim Ryan

1
@TimRyan間違いなく。答えの最後の部分を見ると、jarを--jarsフラグドライバー/エグゼキューターのクラスパスの両方に渡します。
Yuval Itzchakov 2016

1
結局、環境変数をに注入zeppelin-env.shて追加--jarsする方法を見つけましたSPARK_SUBMIT_OPTIONS。うまくいきました。私が使用するURI形式は--jars=local:///mnt/dir/file.jarです。
Mike

4

の別のアプローチは、ユーザーがオプションでクラスパスに追加しているjarに優先順位を与えることにより、依存関係の負荷の優先順位を変更し、それにより、spark-jobの動作を変更するspark-submit中spark 2.1.0に使用--conf spark.driver.userClassPathFirst=trueする--jarsことです。


2
火花を壊す可能性があるため、これには注意する必要があります。これは最後のオプションソリューションです。確かではありませんが、yarn-clientモードで使用している場合、ヤーンとインターフェイスするレイヤーにも干渉する可能性があります。
ヨーヨー2017

頭を上げてくれてありがとう。古いバージョンのサーバーに確実に存在するjarを1つだけ優先する方法はありますか?物理的に置き換えることはできず、使用したくないことがわかっていますか?
スタニスラフ

1
その場合、あなたが提案したとおりに試すことができると思います。それは絶対的なノーだとは言わなかった。また、オプションが「実験的」としてマークされていることにも注意してください-注意してください!ライブラリのあるバージョンを別のバージョンよりも優先させる安全な方法はありません。一部の実装では、ライブラリの1つを異なる名前空間に移動することでこれが解決されるため、両方のバージョンを同時に使用できます。
YoYo 2017

1

yarnデプロイモードの場合のjarおよびクラスパスに関連するその他の設定可能なSparkオプションは次のとおりです
。sparkのドキュメントから、

spark.yarn.jars

YARNコンテナーに配布するSparkコードを含むライブラリーのリスト。デフォルトでは、YARN上のSparkはローカルにインストールされたSpark jarを使用しますが、Spark jarはHDFS上の誰でも読み取り可能な場所に置くこともできます。これにより、YARNはそれをノードにキャッシュできるため、アプリケーションを実行するたびに配布する必要がなくなります。たとえば、HDFSのjarを指すには、この構成をhdfs:/// some / pathに設定します。グロブは許可されています。

spark.yarn.archive

YARNキャッシュに配布するために必要なSpark jarを含むアーカイブ。設定されている場合、この構成はspark.yarn.jarsを置き換え、アーカイブはすべてのアプリケーションのコンテナーで使用されます。アーカイブのルートディレクトリにjarファイルが含まれている必要があります。前のオプションと同様に、アーカイブをHDFSでホストして、ファイルの配布を高速化することもできます。

ユーザーはこのパラメーターを構成してjarを指定できます。jarは、Sparkドライバーのクラスパスに含まれます。


1

--master yarn-clusterでspark-submitを使用すると、アプリケーションのjarと--jarsオプションに含まれているjarが自動的にクラスターに転送されます。--jarsの後に指定するURLはコンマで区切る必要があります。そのリストは、ドライバーとエグゼキューターのクラスパスに含まれています

例:

spark-submit --master yarn-cluster --jars ../lib/misc.jar、../lib/test.jar --class MainClass MainApp.jar

https://spark.apache.org/docs/latest/submitting-applications.html


0

使用には制限があります。ファイルの--jars場所にディレクトリを指定する場合jar/xml、ディレクトリの拡張は許可されません。これは、各jarに絶対パスを指定する必要がある場合を意味します。

指定--driver-class-pathし、yarnクラスターモードで実行している場合、ドライバークラスは更新されません。タブ環境のスパークUIまたはスパーク履歴サーバーでクラスパスが更新されているかどうかを確認できます。

ディレクトリ拡張を含むjarを渡すために機能し、yarn clusterモードで機能する--confオプションはオプションでした。ドライバーとエグゼキューターのクラスパスをとして渡すことをお勧めします--conf。これにより、それらがSparkセッションオブジェクト自体に追加され、それらのパスがSpark構成に反映されます。ただし、jarはクラスタ全体で同じパスに配置してください。

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

明けましておめでとうございます!
YoYo

新年あけましておめでとうございますYoYo
Tanveer

0

Spark-Submitユーティリティを使用してSparkジョブを送信する一方で、オプションがあります--jars。このオプションを使用すると、jarファイルをスパークアプリケーションに渡すことができます。


この—jarオプションがあることは、元の投稿者によって言及され、さらに複数の回答によってより詳細に議論されました。新しいものを提供しているようではありませんか?
ヨーヨー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.