将JAR文件添加到Spark作业- Spark -submit

真正的…这已经被讨论了很多。

然而,这里有很多模棱两可的地方,并且提供了一些答案……包括在JAR /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文件。

我知道在哪里可以找到Apache Spark主文档,特别是关于如何提交,可用的选项,以及JavaDoc。然而,这仍然给我留下了一些漏洞,尽管它也得到了部分回答。

我希望事情没有那么复杂,希望有人能给我一个清晰简明的答案。

如果我从文档中猜测,似乎--jarsSparkContext addJaraddFile方法是自动分发文件的方法,而其他选项只是修改类路径。

为了简单起见,我可以同时使用这三个主要选项添加其他应用程序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)之间的区别。记住这一点绝对很重要。

185602 次浏览

类路径:

ClassPath受到的影响取决于您提供的内容。有几种方法可以在类路径上设置一些东西:

  • spark.driver.extraClassPath或它的别名--driver-class-path在运行驱动程序的节点上设置额外的类路径。
  • spark.executor.extraClassPath在Worker节点上设置额外的类路径。

如果您希望某个JAR同时作用于Master和Worker,您必须在both标志中分别指定它们。

分隔符:

遵循与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启动一个网状的 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服务器。您必须手动使您的JAR文件通过HDFS、S3或其他对所有节点可用的源对所有工作节点可用。

接受文件的URI

“提交Applications"中,Spark文档很好地解释了文件的可接受前缀:

当使用spark-submit时,应用程序与任何jar一起jar 包含的——jars选项将自动转移到 集群。Spark使用以下URL方案来允许不同的 传播jar的策略:

.
  • file: -绝对路径和file:/ uri由驱动程序的HTTP提供 文件服务器,每个执行程序从驱动程序HTTP提取文件 李服务器。< / >
  • hdfs:, http:, https:, ftp: -这些下拉文件和jar文件
  • local: -以local:/ is开头的URI 期望作为每个工作节点上的本地文件存在。这意味着 不会产生网络IO,适用于大文件/ jar 这些文件被推送到每个worker,或者通过NFS、GlusterFS等共享
注意jar和文件被复制到每个的工作目录中

. 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,然后

.conf文件中的选项

所以一定要把这些值设置在正确的位置,这样当一个优先级高于另一个时,你就不会感到惊讶了。

让我们分析一下问题中的每个选项:

  • --jars vs SparkContext.addJar:它们是相同的。只有一个是通过Spark提交设置的,一个是通过代码设置的。选择一个更适合你的。需要注意的一件重要的事情是,使用这些选项中的任何一个没有将JAR文件添加到您的驱动程序/执行程序类路径。你需要在两者上使用extraClassPath配置显式地添加它们。
  • SparkContext.addJar vs SparkContext.addFile:当你的代码中需要使用依赖时,使用前者。当您只是想将任意文件传递给工作节点时,请使用后一种方法,这在代码中不是运行时依赖项。
  • --conf spark.driver.extraClassPath=...--driver-class-path:这些都是别名,你选择哪个并不重要
  • --conf spark.driver.extraLibraryPath=..., or --driver-library-path ...同上,别名。
  • --conf spark.executor.extraClassPath=...:当你有一个依赖项不能包含在über JAR中(例如,因为库版本之间存在编译时冲突),并且你需要在运行时加载时使用此选项。
  • --conf spark.executor.extraLibraryPath=...这是作为JVM的java.library.path选项传递的。当您需要一个对JVM可见的库路径时,可以使用这个选项。
为了简单起见,我可以添加额外的 应用程序jar文件使用3个主要选项同时:

你可以安全地假设这只适用于客户端模式,而不是集群模式。正如我之前所说。另外,你给出的例子有一些多余的参数。例如,将JAR文件传递给--driver-library-path是无用的。如果你想让它们在你的类路径上,你需要将它们传递给extraClassPath。最终,当你在驱动程序和worker上部署外部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

Apache Spark 2.1.0中的另一种方法是在Spark -submit过程中使用--conf spark.driver.userClassPathFirst=true,这将通过赋予用户使用--jars选项添加到类路径中的JAR文件优先级来改变依赖加载的优先级,从而改变Spark -job的行为。

使用--jars有一个限制:如果你想为jar/xml文件指定一个目录,它不允许目录扩展。这意味着您需要为每个JAR文件指定一个绝对路径。

如果你指定--driver-class-path并且你在yarn集群模式下执行,那么驱动类不会被更新。我们可以在Spark UI下或在tab环境下的Spark历史服务器下验证类路径是否被更新。

为我传递包含目录扩展和在yarn集群模式下工作的JAR文件的选项是--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

当我们使用Spark -submit实用程序提交Apache Spark作业时,有一个选项--jars。使用这个选项,我们可以将JAR文件传递给Spark应用程序。

在部署模式为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

包含需要的Spark jar分发到YARN缓存的存档。如果设置了,则 配置替换spark.yarn.jars和存档使用在所有 应用程序的容器。归档文件的根目录中应该包含jar文件。 与前面的选项一样,存档也可以托管在HDFS上,以加快文件的速度 分布。< / p >

用户可以配置这个参数来指定他们的JAR文件,这些文件会被包含在Spark驱动程序的类路径中。

当使用spark-submit with——master yarn-cluster时,应用程序JAR文件以及包含——罐子选项的任何JAR文件将自动传输到集群。——罐子之后提供的url必须用逗号分隔。该列表包含在驱动程序和执行程序类路径中

例子:

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

参考

提交申请

我知道添加带有--jars选项的jar会自动将它添加到类路径中。

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

该列表包含在驱动程序和执行程序类路径中。