HDP 2.6环境下Spark-submit加载RequestHedgingRMFailoverProxyProvider类失败求助
问题根源
你碰到的这个问题我之前在HDP环境部署Spark时也遇到过,核心是Spark自带的Hadoop依赖和HDP集群的Hadoop版本不兼容,再加上Spark默认的类加载顺序搞的鬼:
- Spark 2.2.1默认捆绑了原生Hadoop 2.7.3的依赖包,其中
hadoop-yarn-common-2.7.3.jar确实没有org.apache.hadoop.yarn.client.RequestHedgingRMFailoverProxyProvider这个类——这是HDP为YARN高可用实现的自定义扩展类,属于HDP私有内容。 - 虽然你的
yarn.application.classpath配置了HDP的hadoop-yarn-client目录,但Spark启动时会优先加载自身jars目录下的Hadoop相关jar,导致HDP的jar被“覆盖”,自然找不到目标类。 - 而你手动用
--jars或者把HDP的jar复制到Spark jars目录时,又会触发类版本冲突:Spark自带的旧jar和HDP的jar里有大量相同类(比如org.apache.hadoop.yarn.client.api.YarnClient),但版本和内部实现有差异,类加载器加载旧版本类后,新版本类访问其私有成员就会抛出IllegalAccessError。
解决方法
核心思路是让Spark彻底放弃自身捆绑的Hadoop依赖,优先使用HDP集群提供的Hadoop类路径,具体步骤如下:
1. 修改Spark环境变量配置
编辑Spark安装目录下的conf/spark-env.sh(如果没有就复制spark-env.sh.template重命名),添加一行配置:
export SPARK_DIST_CLASSPATH=$(hadoop classpath)
这个命令会自动获取HDP集群中Hadoop的完整类路径,让Spark的类加载器启动时优先加载HDP的所有Hadoop相关jar,完全替代自身的旧依赖。
2. 验证配置有效性
提交一个简单的Spark任务测试,比如运行自带的Pi计算示例:
spark-submit --class org.apache.spark.examples.SparkPi $SPARK_HOME/examples/jars/spark-examples_2.11-2.2.1.jar 10
如果任务能正常输出计算结果,说明类加载顺序已经调整正确,之前的找不到类和权限错误都会消失。
3. 备选方案(如果上述方法不生效)
如果SPARK_DIST_CLASSPATH没起作用,可以编辑conf/spark-defaults.conf,强制指定Driver和Executor使用HDP的Hadoop类路径:
spark.driver.extraClassPath /usr/hdp/current/hadoop-yarn-client/*:/usr/hdp/current/hadoop-client/* spark.executor.extraClassPath /usr/hdp/current/hadoop-yarn-client/*:/usr/hdp/current/hadoop-client/*
注意:这种方式需要手动列举路径,不如SPARK_DIST_CLASSPATH灵活,优先推荐第一种方法。
4. 避坑提醒
- 绝对不要把HDP的
hadoop-yarn-common.jar复制到Spark的jars目录,也不要用--jars指定这个jar——这会导致类重复加载,必然引发版本冲突和权限错误。 - 建议你的Spark应用用HDP提供的Hadoop依赖重新编译(HDP 2.6的Hadoop是带补丁的2.7.3版本),如果应用是用原生Hadoop 2.7.3编译的,可能还会有隐性兼容性问题。
内容的提问来源于stack exchange,提问作者awenclaw
相关产品推荐
相关产品推荐

