使用spark-submit提交任务时能否禁用集群特定jar包?
spark-submit 没有提供直接「禁用集群侧特定预置库」的独立参数,但存在多个仅作用于当前任务生命周期的配置方案,可以完全在不修改集群全局classpath、不影响其他业务任务的前提下解决依赖冲突问题,具体可按场景选择:
优先使用类加载优先级配置覆盖冲突版本
提交任务时追加以下两个配置,让Driver和Executor优先加载用户自带的依赖,而非集群预置classpath中的版本:--conf spark.driver.userClassPathFirst=true --conf spark.executor.userClassPathFirst=true该配置是任务级生效,不会修改集群任何全局配置,80%以上的常规依赖冲突(比如Jackson、Guava、Protobuf版本不匹配)都可以通过这个方式解决。注意Spark 2.x早期版本该特性属于实验性功能,Spark 3.x版本已稳定可用。
通过胖包Shade重定位从根源隔离冲突
打业务Jar包时使用Maven Shade/Gradle Shadow插件,将存在版本冲突的依赖进行包路径重定位,比如把你项目依赖的高版本Guava从com.google.common重定位到你项目专属的路径如com.your.biz.shaded.guava,打包后冲突类的全限定名和集群预置类完全不同,JVM加载时不会产生任何版本冲突,这是最稳妥的零侵入方案,完全不需要调整集群或提交参数的类路径配置。任务级替换/排除集群预置依赖
默认配置下spark.yarn.jars参数会指向集群公共的Spark依赖路径,你可以在提交时自定义该参数的值,剔除掉存在冲突的集群Jar,替换为你自己准备的对应版本Jar,配置仅对当前任务生效,任务运行结束后YARN会自动清理分发的临时依赖缓存,不会影响公共环境。
针对YARN Client模式下Driver侧的类路径冲突,也可以在执行spark-submit的当前Shell会话中临时修改classpath变量,过滤掉冲突的Jar包,示例命令:# 临时剔除当前会话classpath里冲突的低版本guava,仅当前终端生效 export SPARK_DIST_CLASSPATH=$(echo $SPARK_DIST_CLASSPATH | tr ':' '\n' | grep -v "guava-11.0.2.jar" | tr '\n' ':') # 再执行spark-submit提交任务 spark-submit --master yarn --deploy-mode client your-job.jar该操作不会修改全局的
spark-env.sh或服务器classpath配置,关闭当前Shell后临时修改自动失效。调整用户依赖的加载顺序
提交任务时通过--jars传入你需要的自定义版本依赖,同时追加以下配置将用户依赖放在类路径最前端,优先级高于集群预置的SPARK_HOME/lib下的依赖:--conf spark.driver.extraClassPath=./your-custom-deps.jar --conf spark.executor.extraClassPath=./your-custom-deps.jar
注意:不要通过直接修改集群节点
SPARK_HOME/jars下的Jar、全局spark-env配置的方式解决单任务冲突,会导致其他依赖原有版本的任务运行失败。
内容的提问来源于stack exchange,提问作者user15510132

