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

2022-08-31 06:20:43

真。。。它已经被讨论了很多。

但是,有很多歧义和提供的一些答案...包括在 jars/executor/driver 配置或选项中复制 JAR 引用。

模棱两可和/或省略的细节

对于每个选项,应澄清以下含糊不清、不明确和/或省略的详细信息:

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

它影响的选项:

  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。然而,这给我留下了相当多的漏洞,尽管它也得到了部分回答。

我希望它不是那么复杂,并且有人可以给我一个清晰简洁的答案。

如果我从文档中猜测,似乎 和 and 方法是自动分发文件的方法,而其他选项只是修改 ClassPath。--jarsSparkContextaddJaraddFile

为了简单起见,我可以同时使用三个主要选项添加其他应用程序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

类路径:

类路径会受到影响,具体取决于您提供的内容。有几种方法可以在类路径上设置某些内容:

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

如果您希望某个 JAR 同时影响主设备和工作线程,则必须在 TWO 标志中分别指定这些内容。

分隔字符:

遵循与 JVM 相同的规则

  • Linux: 冒号,:
    • 例如:--conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar:/opt/prog/aws-java-sdk-1.10.50.jar"
  • 窗口:分号,;
    • 例如:--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 选择了要在其上执行驱动程序进程的领先 Worker 节点。这意味着作业不是直接从节点运行的。在这里,Spark不会设置HTTP服务器。您必须通过 HDFS、S3 或所有节点可用的其他源手动使 JAR 文件可供所有工作节点使用。

文件已接受的 URI

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

使用 spark-submit 时,应用程序 jar 以及 --jars 选项中包含的任何 jar 将自动传输到群集。Spark 使用以下 URL 方案来允许使用不同的策略来分发 jar:

  • 文件: - 绝对路径和文件:/URI 由驱动程序的 HTTP 文件服务器提供,每个执行程序都从驱动程序 HTTP 服务器拉取文件。
  • hdfs:, http:, https:, ftp: - 这些按预期从 URI 下拉文件和 JAR
  • local: - 以 local:/ 开头的 URI应作为本地文件存在于每个工作节点上。这意味着不会产生网络IO,并且对于推送到每个工作线程或通过NFS,GlusterFS等共享的大文件/ JAR非常有效。

请注意,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 文档中提到:spark-submit

在属性文件中指定为标志或属性文件的任何值都将传递到应用程序,并与通过 SparkConf 指定的值合并。直接在 SparkConf 上设置的属性具有最高优先级,然后将标志传递给 spark-submit 或 spark-shell,然后是 spark-defaults.conf 文件中的选项

因此,请确保将这些值设置在适当的位置,这样当一个值优先于另一个值时,您就不会感到惊讶。

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

  • --jarsvs :这些是相同的。只有一个是通过 Spark 提交设置的,一个是通过代码设置的。选择一个更适合你的。需要注意的一件重要事情是,使用这些选项中的任何一个都不会将 JAR 文件添加到驱动程序/执行器类路径中。您需要使用两者的配置显式添加它们。SparkContext.addJarextraClassPath
  • SparkContext.addJarvs :当您有一个依赖项需要与代码一起使用时,请使用前者。当您只想将任意文件传递给工作线程节点时,请使用后者,这不是代码中的运行时依赖项。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 的选项传递的。当您需要对 JVM 可见的库路径时,请使用此选项。java.library.path

可以安全地假设,为简单起见,我可以同时使用3个主要选项添加其他应用程序jar文件:

您可以放心地假定这仅适用于客户端模式,而不是群集模式。正如我之前所说。此外,您给出的示例有一些多余的参数。例如,将 JAR 文件传递到是无用的。如果您希望它们位于类路径上,则需要将它们传递给。最终,当您在驱动程序和工作线程上部署外部 JAR 文件时,您需要:--driver-library-pathextraClassPath

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

答案 2

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


推荐