Spark 依赖包来源
我们知道Spark application运行加载依赖有三个地方:
- SystemClasspath -- Spark安装时候提供的依赖包 【SystemClassPath】
- Spark-submit --jars 提交的依赖包 【UserClassPath】
- Spark-submit app.jar或者shadowJar打的jar 【UserClassPath】
Spark 依赖包默认优先级
通过测试发现class的默认加载顺序如下:
1. SystemClasspath -- Spark安装时候提供的依赖包
2. UserClassPath -- Spark-submit --jars 提交的依赖包 或用户的app.jar
SystemClasspath 系统安装的包,默认优先使用环境的包,这样更加稳定安全。
spark-submit --jars 在默认spark环境里没有需要的包时,自己上传提供。
观察方法: spark-submit 的时候添加参数
--driver-java-options -verbose:class
测试环境:
SPARK2-2.2.0.cloudera1-1.cdh5.12.0.p0.142354
1.8.0_171 (Oracle Corporation)
查看环境包依赖情况: Environment tab里搜索想要的依赖包。
依赖包冲突解决方案
- spark.{driver/executor}.userClassPathFirst
该配置的意思是优先使用用户路径下的依赖包。通常是系统默认提供的依赖包版本较低,需要使用用户自己提供的依赖包,使用该选项可以解决很多问题,但是也容易引起新的冲突,所以不推荐使用。
- spark.{driver/executor}.extraClassPath
某些时候同一个类的两个不同版本被加载进ClassLoader,link的时候发生错误。这种冲突就需要使用extraClassPath手动指定版本。该选项指定的依赖包具有最高优先级。需要指定多个包时,中间使用":"来分割。稳定可靠,推荐使用。
注意:extraClassPath=jarName 不用给path。 例如:
--jars hdfs://.../snappy-java-version.jar \
--conf "spark.driver.extraClassPath=snappy-java-version.jar" \
--conf "spark.executor.extraClassPath=snappy-java-version.jar" \
比如曾经的例子 snappy-java包冲突:
Spark job jar包冲突解决方案_java.lang.unsatisfiedlinkerror: org.xerial.snappy.-CSDN博客
使用userClassPathFirst后,报如下错误:
org.xerial.snappy.SnappyNative.maxCompressedLength(I)I
java.lang.UnsatisfiedLinkError: org.xerial.snappy.SnappyNative.maxCompressedLength(I)I
通过 “--driver-java-options -verbose:class” 查看加载的类:SnappyNative分别从两个包snappy-java-1.1.4.jar [UserClassPath], snappy-java-1.0.4.1.jar [SystemClassPath] 加载进入ClassLoader,
link的时候不能确定使用哪个版本就报上面的错误。这种情况就必须使用“extraClassPath”来解决。
总结
A)在我们提交一个spark2 程序时,系统没有的包--jars 提交;
B)在需要使用系统中已有的包的不同版本时,使用spark.{driver/executor}.extraClassPath来指定。
参考文章: