Spark3.2读取S3报IAMInstanceCredentialsProvider类找不到异常
问题根因
- 第一处错误是Hadoop配置项的前缀使用错误:
spark.hadoop.前缀仅用于在Spark配置文件、spark-submit参数中声明需要透传给Hadoop的配置项,如果你是直接通过spark.sparkContext.hadoopConfiguration.set()方法操作Hadoop配置对象,参数名不需要加这个前缀。你代码里设置凭证提供者的参数名多写了前缀,相当于设置了一个无效参数,真正的fs.s3a.aws.credentials.provider配置项根本没有被赋值,程序会使用当前Hadoop版本的默认值。 - 第二处问题是Hadoop版本的默认行为变化+依赖不匹配:Hadoop 3.2.x版本的S3A模块默认将
org.apache.hadoop.fs.s3a.auth.IAMInstanceCredentialsProvider放在凭证提供者列表的首位,这个类是Hadoop 3.x新增的,在你之前用的Hadoop 2.8.5版本中不存在。同时你引入的Hadoop依赖版本(3.2.1)和Spark 3.2.0内置的Hadoop版本(3.2.0)不一致,很容易出现类加载冲突,导致程序找不到对应的类抛出异常。 - 旧版本能正常运行的原因:Hadoop 2.8.5的S3A默认凭证提供者列表首位就是你需要的
SimpleAWSCredentialsProvider,哪怕你当时配置写错了前缀没生效,默认逻辑也能读取到你设置的AK/SK完成认证,所以不会报错。
修复方案
- 修正代码中的配置项名称,去掉多余的前缀,将凭证提供者的配置改为:
spark.sparkContext.hadoopConfiguration.set("fs.s3a.aws.credentials.provider", "org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider")
- 对齐所有Hadoop相关依赖的版本,和Spark 3.2.0内置的Hadoop 3.2.0保持一致,避免版本冲突。修正后的依赖配置参考如下,注意将Spark核心依赖标记为Provided,避免和集群内置的Spark jar包冲突:
libraryDependencies += "org.apache.spark" %% "spark-core" % "3.2.0" % Provided libraryDependencies += "org.apache.spark" %% "spark-sql" % "3.2.0" % Provided libraryDependencies += "org.apache.hadoop" % "hadoop-aws" % "3.2.0" libraryDependencies += "org.apache.hadoop" % "hadoop-client" % "3.2.0"
- 如果你是在AWS EC2、EKS、EMR等环境运行任务,且已经给计算节点绑定了有S3访问权限的IAM角色,甚至不需要手动配置AK/SK和凭证提供者类,只要保证hadoop-aws包版本和集群Hadoop版本一致,S3A会自动通过IAM角色完成认证,安全性更高。
内容的提问来源于stack exchange,提问作者R.M
相关产品推荐
相关产品推荐

