signed

QiShunwang

“诚信为本、客户至上”

如何添加多个jar到spark-submit的classpath?

2021/4/26 15:22:38   来源:

当使用Spark -submit提交Spark应用程序时,经常需要在类路径中包含多个第三方jar, Spark支持多种方式向类路径中添加依赖jar。

1. 将jar添加到classpath

可以使用spark-submit、spark-defaults.conf和SparkConf属性将多个第三方jar添加到类路径中,在使用这些选项之前,您需要了解这些选项如何应用的优先级。下面是它们按顺序应用的优先级。

  1. 直接在SparkConf上设置的属性优先级最高。

  2. 第二个优先级是spark-submit选项。

  3. 最后,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/

http://spark.apache.org/docs/2.4.7/configuration.html

http://spark.apache.org/docs/2.4.7/running-on-yarn.html