当使用Spark -submit提交Spark应用程序时,经常需要在类路径中包含多个第三方jar, Spark支持多种方式向类路径中添加依赖jar。
1. 将jar添加到classpath
可以使用spark-submit、spark-defaults.conf和SparkConf属性将多个第三方jar添加到类路径中,在使用这些选项之前,您需要了解这些选项如何应用的优先级。下面是它们按顺序应用的优先级。
-
直接在SparkConf上设置的属性优先级最高。
-
第二个优先级是spark-submit选项。
-
最后,spark-defaults.conf文件中指定的属性。
当您在不同的地方设置jars时,请记住它的优先级。使用带有--verbose选项的spark-submit可以获得关于spark 使用jars的更多细节
1.1. Adding jars to the classpath
可以使用Spark submit选项--jar添加jar,使用此选项您可以添加单个jar或多个以逗号分隔的jar。
示例:# yarn cluster提交
spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --driver-memory 1g --executor-memory 1g --executor-cores 1 --conf "spark.driver.extraJavaOptions=-Dlog4j.configuration=log4j-driver.xml" --conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=log4j-executor.xml" --files=/opt/test/conf/log4j-driver.xml,/opt/test/conf/log4j-executor.xml --jars "/opt/test/slf4j-api-1.7.25.jar" spark-examples_2.11-2.4.7.jar 10
必要条件:运行spark-submit命令的机器上必须存在对应的jar
或者,你也可以使用SparkContext.addJar()
1.2. Adding all jars from a folder to classpath
如果你有很多jar,想象一下用逗号分隔所有这些jar,当你必须更新jar的版本时,维护它将是一场噩梦。
$(echo /path/*.jar | tr ' ' ',')语句通过在文件夹中附加所有jar名称创建一个逗号分隔的字符串。
spark-submit -- class com.spark.examples.WordCountExample \
--jars $(echo /path/*.jar | tr ' ' ',') \
your-application.jar
1.3. 通过spark-submit 参数 --packages
使用spark-submit提交命令的参数: --packages, 集群中服务需要该包的的时候,都是从给定的maven地址直接下载
示例:spark-shell --packages mysql:mysql-connector-java:5.1.27 --repositories http://maven.aliyun.com/nexus/content/groups/public/
必要条件:
nodeManager能访问maven地址
1.4. Adding jars with spark-defaults.conf
您也可以在$SPARK_HOME/conf/spark-defaults.conf上指定jar,但这不是一个更好的选择,并且您在这里指定的库优先级较低。
#Add jars to driver classpath
spark.driver.extraClassPath /path/first.jar:/path/second.jar
#Add jars to executor classpath
spark.executor.extraClassPath /path/first.jar:/path/second.jar
1.5. Using SparkConf properties
This takes the high priority among other configs.
spark = SparkSession \
.builder \
.appName("SparkExamples.com") \
.config("spark.yarn.dist.jars", "/path/first.jar,/path/second.jar") \
.getOrCreate()
2. 创建uber or assembly jar
通过包含应用程序类和所有第三方依赖项来创建assembly or uber jar。您可以使用Maven shade plugin或等效的 SBT assembly来实现这一点。
通过这样做,您不必担心将jar添加到类路径中,因为所有依赖项都已经是您的uber jar的一部分了。
maven-shade-plugin插件可以解决冲突双方的包互相不兼容情况,其原理是修改其中任意一方的依赖路径,来解决。比如package A依赖package org.apache.common_v1,package C依赖package org.apache.common_v2,此时可以将package B_v1重新打包成package shade.org.apache.common_V1,而后修改package A的所有包引入代码,import org.apache.common修改成import shade.org.apache.common
<build>
<finalName>${project.name}-${project.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<!-- <version>3.1.0</version>-->
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<!-- 指定程序入口 -->
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.apache.learnspark.Main</mainClass>
</transformer>
</transformers>
<!--通过重命名解决jar冲突问题-->
<relocations>
<relocation>
<pattern>com.google.protobuf</pattern>
<shadedPattern>shaded.com.google.protobuf</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
3. Adding jars to Spark Driver
有时你可能需要只向Spark驱动添加一个jar,你可以使用--driver-class-path或--conf Spark .driver. extraclasspath来完成
spark-submit -- class com.sparkbyexamples.WordCountExample \
--jars $(echo /path/jars/*.jar | tr ' ' ',') \
--driver-class-path jar-driver.jar
your-application.jar
4. 其它方式
--conf spark.driver.extraLibraryPath=/path/
# or use below, both do the same
--driver-library-path /path/
参考
https://sparkbyexamples.com/spark/add-multiple-jars-to-spark-submit-classpath/