DataStax环境Spark读取ADLS Gen2 CSV的Hadoop版本冲突问题求助
你遇到的问题核心是DSE默认类加载机制会优先加载内置的Hadoop 2.7.1.4版本jar包,导致你自行引入的高版本Hadoop依赖无法生效,可按照以下步骤逐步修复:
1. 调整Spark类加载优先级
在spark-submit提交参数中添加两个配置,强制让用户自定义依赖的优先级高于集群内置依赖:
--conf spark.driver.userClassPathFirst=true --conf spark.executor.userClassPathFirst=true
注意:开启该配置后需要确保你打入jar包的依赖和DSE内置的Spark核心依赖没有冲突,Spark相关依赖必须设为provided scope
2. 优化pom.xml配置
2.1 锁定Hadoop依赖版本
在pom.xml中添加dependencyManagement节点,强制所有Hadoop相关依赖的版本统一为2.10.1,避免传递依赖引入旧版本:
<dependencyManagement> <dependencies> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.10.1</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.10.1</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-azure</artifactId> <version>2.10.1</version> </dependency> </dependencies> </dependencyManagement>
2.2 调整依赖scope
将Spark相关依赖的scope设为provided,避免重复打入jar包引发冲突:
<dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-sql_2.11</artifactId> <version>2.4.0</version> <scope>provided</scope> </dependency>
2.3 替换打包插件(可选,推荐)
将maven-assembly-plugin替换为maven-shade-plugin,更灵活的控制依赖打包规则,避免类冲突:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>org.example.App</mainClass> </transformer> </transformers> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin>
3. 调整spark-submit提交脚本
调整后的完整提交脚本如下:
sudo dse -u user -p password spark-submit --verbose --name "SPARK" --deploy-mode client --executor-memory 8G --num-executors 6 --executor-cores 3 --driver-memory 4g --conf spark.cassandra.auth.username=user --conf spark.cassandra.auth.password=password --conf "spark.rpc.askTimeout=2500" --conf "spark.cassandra.connection.keepAliveMS=10800000" --conf "spark.cassandra.query.retry.count=-1" --conf spark.driver.userClassPathFirst=true --conf spark.executor.userClassPathFirst=true example.jar
如果仍然不生效,可以额外添加--jars hadoop-common-2.10.1.jar,hadoop-azure-2.10.1.jar参数,明确指定高版本jar包路径。
4. 验证类加载结果
你可以在代码中添加一行日志打印ProviderUtils类的来源,确认加载的版本是否正确:
println(org.apache.hadoop.security.ProviderUtils.class.getProtectionDomain().getCodeSource.getLocation)
备选方案(如果高版本Hadoop冲突过多)
如果开启用户类路径优先后出现其他兼容问题,可以选择适配DSE内置Hadoop版本,将hadoop-client和hadoop-azure的版本降为2.7.7,该版本已经支持ABFS协议,同时和内置的2.7.1.4版本API兼容性更高,不会出现大范围类冲突。
内容的提问来源于stack exchange,提问作者Nessrine BEN ZEINEB

