Jupyter Notebook上无法将S3托管CSV加载为Spark DataFrame
问题原因
当前报错No FileSystem for scheme "s3"由三个配置错误共同导致:
PYSPARK_SUBMIT_ARGS配置时机错误:环境变量设置在import pyspark之后,PySpark启动时已经完成环境参数加载,后续设置的依赖参数完全不会生效。- 依赖包配置错误:引入的
com.amazonaws:aws-java-sdk-pom:1.10.34是Maven父依赖描述文件,不是可运行的实际SDK包,且版本和hadoop-aws 2.7.2不匹配,无法提供S3文件系统实现类。 - 协议与实现不匹配:hadoop-aws 2.7.x版本默认不提供
s3://协议的文件系统实现,该版本官方支持的S3访问协议为s3a://,未显式配置实现类的情况下无法识别s3开头的路径。
修复步骤
- 调整配置顺序,替换正确的依赖包
必须在导入pyspark模块前完成环境变量设置,替换无效的pom依赖为版本匹配的正式SDK包:
import os # 环境变量配置必须放在import pyspark之前 os.environ['PYSPARK_SUBMIT_ARGS'] = '--packages com.amazonaws:aws-java-sdk:1.7.4,org.apache.hadoop:hadoop-aws:2.7.3 pyspark-shell' import pyspark from pyspark.sql import SparkSession
- 初始化SparkSession时显式配置S3文件系统参数
如果EC2实例已经绑定了拥有S3访问权限的IAM角色,直接用实例角色凭证即可,无需硬编码密钥:
spark = SparkSession.builder \ .appName('test') \ # 指定s3a协议的文件系统实现类 .config("spark.hadoop.fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem") \ # 使用EC2实例绑定的IAM角色作为凭证来源 .config("spark.hadoop.fs.s3a.aws.credentials.provider", "com.amazonaws.auth.InstanceProfileCredentialsProvider") \ # 未配置IAM角色的场景,注释上面的provider配置,打开下面两行填写实际密钥 # .config("spark.hadoop.fs.s3a.access.key", "你的AWS访问密钥ID") # .config("spark.hadoop.fs.s3a.secret.key", "你的AWS秘密访问密钥") .getOrCreate()
- 替换访问路径的协议头
将读取代码中s3://开头的路径替换为s3a://,匹配配置好的文件系统实现:
%%time df = spark.read.csv(f"s3a://{AWS_BUCKET}/prices/{ts}_all_prices_{user}.csv", inferSchema=True, header=True)
排查校验点
- 依赖加载校验:Spark启动后查看Spark UI的Environment页面,确认
spark.jars.packages项包含配置的两个依赖,控制台无依赖下载失败的报错。如果网络原因导致--packages拉取依赖失败,可直接下载对应版本的aws-java-sdk-1.7.4.jar和hadoop-aws-2.7.3.jar放到Spark安装目录的jars文件夹下,跳过在线拉取步骤。 - 权限校验:确认EC2实例绑定的IAM角色拥有目标S3桶的
s3:ListBucket、s3:GetObject权限,避免配置正确但出现权限拒绝错误。 - 版本校验:如果使用更高版本的Hadoop(3.x+),需要同步升级aws-java-sdk到对应匹配版本,避免类版本不兼容问题。
内容的提问来源于stack exchange,提问作者Katsu
相关产品推荐
相关产品推荐

