如何修改Spark源码并在集群环境中运行?
解决Spark自定义JDBCUtils在集群运行不生效的问题
可行方案一:重新编译Spark源码并替换集群Jar包(最彻底)
这是修改Spark核心类后最可靠的方式,确保集群所有节点都使用你修改后的版本:
- 下载与集群Spark版本完全一致的源码,将你的
org/apache/spark/sql/execution/datasources/JDBCUtils.scala替换到源码对应目录 - 执行Spark官方编译命令(以Maven为例):
build/mvn -DskipTests clean package - 找到编译产物中的
spark-sql_<scala-version>-<spark-version>.jar,替换集群所有节点$SPARK_HOME/jars/目录下的同名Jar包 - 重启Spark集群服务
可行方案二:强制Executor优先加载用户Jar类(无需重编译Spark)
利用Spark的类加载优先级配置,让Executor优先加载你Jar中的修改类:
- 将你的项目打包为Fat Jar(确保修改后的
JDBCUtils类包含其中,Spark SQL依赖保持provided) - 提交任务时添加以下关键参数:
spark-submit \ --class com.your.package.MainClass \ --master yarn \ --deploy-mode cluster \ --conf spark.driver.userClassPathFirst=true \ --conf spark.executor.userClassPathFirst=true \ --conf spark.yarn.dist.jars=your-fat-jar.jar \ your-fat-jar.jarspark.[driver/executor].userClassPathFirst=true:强制类加载器优先加载用户Jar中的类,而非Spark自带Jarspark.yarn.dist.jars:确保你的Fat Jar被分发到所有Executor节点
为什么你之前的尝试无效?
- 非provided依赖+MergeStrategy:集群Executor的类路径中,Spark官方Jar优先级高于用户Jar,即使打包了修改类,依然会加载官方版本
spark.executor.extraClassPath:仅将Jar追加到类路径,不改变Spark自带类的加载优先级spark.jars.excludes:无法排除Spark SQL核心Jar,否则Spark服务会直接启动失败- 仅设置
spark.driver.userClassPathFirst:只影响Driver端类加载,Executor端依然使用默认优先级加载官方类
内容的提问来源于stack exchange,提问作者Gar Garrison
相关产品推荐
相关产品推荐

