在Cloudera YARN运行Spark2.1应用时遇两类错误求助
解决Cloudera CDH 5.10.2上Spark 2.1 on YARN的两类错误
1. java.lang.ClassCastException: org.apache.hadoop.conf.Configuration cannot be cast to org.apache.hadoop.yarn.conf.YarnConfiguration
问题原因
这个错误本质是类加载冲突或者代码强制转换不当:
- 要么是你代码里直接把通用的
Configuration对象强转成YarnConfiguration,但实际获取的配置实例并不是YarnConfiguration类型; - 要么是你的应用依赖的Hadoop/YARN类版本和Cloudera集群提供的版本不一致,导致类加载器加载了不同版本的类,无法互相转换。
解决方案
- 代码调整:别直接强转,改用
YarnConfiguration的构造方法包装原有配置,比如:
这种方式会基于原有配置生成合法的// 错误写法 YarnConfiguration yarnConf = (YarnConfiguration) conf; // 正确写法 YarnConfiguration yarnConf = new YarnConfiguration(conf);YarnConfiguration实例,同时继承所有配置属性。 - 提交参数优化:
- 用
spark-submit时,不要把Hadoop/YARN的核心jar包打包进你的应用或者通过--jars指定,Cloudera集群已经提供了这些类,重复依赖会导致类加载混乱; - 可以尝试添加类路径优先级配置(注意Spark 2.1和CDH 5.10.2兼容,测试后使用):
让用户自定义的类路径优先于集群提供的路径,避免版本冲突。spark-submit --conf spark.driver.userClassPathFirst=true --conf spark.executor.userClassPathFirst=true ...
- 用
- 集群检查:确认CDH-5.10.2的YARN相关parcel部署正常,集群节点的类路径没有被第三方jar包污染。
2. SLF4J多绑定冲突问题
问题原因
你的应用依赖的slf4j-log4j12 jar包和Cloudera CDH自带的版本(1.7.5)重复了,两个不同版本的jar都包含StaticLoggerBinder类,SLF4J无法确定使用哪个绑定,所以抛出警告。
解决方案
- 依赖管理(构建阶段):如果用Maven/Gradle构建应用,排除掉依赖中自带的
slf4j-log4j12,只保留集群提供的版本。比如Maven中在相关依赖里添加排除:<exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> - 提交参数控制:
- 用
spark-submit时,直接排除冲突的包:spark-submit --exclude-packages org.slf4j:slf4j-log4j12 ... - 或者指定优先加载CDH的SLF4J jar:
spark-submit --conf spark.driver.extraClassPath=/opt/cloudera/parcels/CDH-5.10.2-1.cdh5.10.2.p0.5/jars/slf4j-log4j12-1.7.5.jar --conf spark.executor.extraClassPath=/opt/cloudera/parcels/CDH-5.10.2-1.cdh5.10.2.p0.5/jars/slf4j-log4j12-1.7.5.jar ...
- 用
- 清理YARN缓存:检查YARN节点的文件缓存目录(比如
/data/yarn/nm/filecache/),删除残留的旧应用依赖jar,避免重复加载冲突的类。
内容的提问来源于stack exchange,提问作者user3725190
相关产品推荐
相关产品推荐

