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

然而,这里有很多模棱两可的地方,并且提供了一些答案……包括在JAR /executor/driver配置或选项中复制JAR引用。

模糊的和/或省略的细节

对于每个选项,应澄清以下模糊、不清楚和/或省略的细节:

如何影响ClassPath 司机 执行程序(用于运行的任务) 这两个 一点也不 分隔字符:逗号、冒号、分号 如果提供的文件是自动分发的 对于任务(给每个执行程序) 用于远程驱动程序(如果在集群模式下运行) 接受的URI类型:本地文件,HDFS, HTTP等。 如果复制到一个公共位置,该位置在哪里(HDFS,本地?)

影响的选项:

——罐子 SparkContext.addJar(…)方法 SparkContext.addFile(…)方法 ——配置spark.driver.extraClassPath =…或者——driver-class-path… ——配置spark.driver.extraLibraryPath =…,或者——driver-library-path… ——配置spark.executor.extraClassPath =… ——配置spark.executor.extraLibraryPath =… 不要忘记,spark-submit的最后一个参数也是一个.jar文件。

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

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

如果我要从文档中猜测,似乎——jars、SparkContext addJar和addFile方法是自动分发文件的方法,而其他选项只是修改ClassPath。

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


类路径:

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

spark.driver.extraClassPath或者它的别名——driver-class-path在运行驱动程序的节点上设置额外的类路径。 在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"

文件地理分布:

这取决于你运行工作的模式:

Client mode - Spark fires up a Netty HTTP server which distributes the files on start up for each of the worker nodes. You can see that when you start your Spark job: 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 Cluster mode - In cluster mode Spark selected a leader Worker node to execute the Driver process on. This means the job isn't running directly from the Master node. Here, Spark will not set an HTTP server. You have to manually make your JAR files available to all the worker nodes via HDFS, S3, or Other sources which are available to all nodes.

接受文件的URI

在“提交应用程序”中,Spark文档很好地解释了文件的可接受前缀:

When using spark-submit, the application jar along with any jars included with the --jars option will be automatically transferred to the cluster. Spark uses the following URL scheme to allow different strategies for disseminating jars: file: - Absolute paths and file:/ URIs are served by the driver’s HTTP file server, and every executor pulls the file from the driver HTTP server. hdfs:, http:, https:, ftp: - these pull down files and JARs from the URI as expected local: - a URI starting with local:/ is expected to exist as a local file on each worker node. This means that no network IO will be incurred, and works well for large files/JARs that are pushed to each worker, or shared via NFS, GlusterFS, etc.

注意,每个jar和文件都被复制到工作目录中 执行器节点上的SparkContext。

如前所述,JAR文件被复制到每个Worker节点的工作目录。具体在哪里?它通常在/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文件中的选项

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

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

--jars vs SparkContext.addJar: These are identical. Only one is set through Spark submit and one via code. Choose the one which suits you better. One important thing to note is that using either of these options does not add the JAR file to your driver/executor classpath. You'll need to explicitly add them using the extraClassPath configuration on both. SparkContext.addJar vs SparkContext.addFile: Use the former when you have a dependency that needs to be used with your code. Use the latter when you simply want to pass an arbitrary file around to your worker nodes, which isn't a run-time dependency in your code. --conf spark.driver.extraClassPath=... or --driver-class-path: These are aliases, and it doesn't matter which one you choose --conf spark.driver.extraLibraryPath=..., or --driver-library-path ... Same as above, aliases. --conf spark.executor.extraClassPath=...: Use this when you have a dependency which can't be included in an über JAR (for example, because there are compile time conflicts between library versions) and which you need to load at runtime. --conf spark.executor.extraLibraryPath=... This is passed as the java.library.path option for the JVM. Use this when you need a library path visible to the 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中的另一种方法是使用——conf Spark .driver。在spark-submit期间userClassPathFirst=true,这会改变依赖加载的优先级,从而改变spark-job的行为,通过赋予用户使用——jars选项添加到类路径中的JAR文件优先级。


使用——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 as部署模式下,与JAR文件和类路径相关的其他可配置Spark选项如下。

在Spark文档中,

spark.yarn.jars 包含要分发到YARN容器的Spark代码的库列表。 默认情况下,YARN上的Spark将使用本地安装的Spark jar,但Spark jar也可以是本地安装的 在HDFS上一个世界可读的位置。这允许YARN将其缓存到节点上,这样就不会发生 需要在每次应用程序运行时分发。例如,要指向HDFS上的jar, 设置为hdfs:///some/path。glob是允许的。

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

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


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

例子:

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

参考

提交的应用程序


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

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

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