本地模式下如何使用PySpark读取S3存储?
在本地pip安装的PySpark中读取S3存储的解决方案
我之前也遇到过完全一样的场景——用pip装的PySpark本地运行,没装独立Hadoop和Spark,要读S3数据。核心问题其实很简单:pip安装的PySpark默认没包含访问S3所需的Hadoop AWS连接器依赖,咱们补上这些依赖再配置好凭证就行。
步骤1:下载兼容的依赖JAR包
Spark 2.3对应的Hadoop版本是2.7.x,必须下载和这个版本匹配的JAR包,否则会有兼容性问题:
hadoop-aws-2.7.3.jar(Spark 2.3默认依赖的Hadoop版本对应的AWS连接器)aws-java-sdk-1.7.4.jar(配合hadoop-aws的AWS SDK核心包)
你可以把这些JAR包放到一个方便的目录,比如虚拟环境根目录下的spark_jars文件夹,或者直接放到虚拟环境的site-packages/pyspark/jars目录里(这样PySpark启动时会自动加载,省得配置路径)。
步骤2:配置SparkConf并加载依赖
下面给你两种配置方式,选一种适合你的就行:
方式1:在代码中指定JAR路径
直接在SparkConf里配置JAR包路径和S3凭证:
from pyspark import SparkConf from pyspark import SparkContext # 初始化Spark配置 conf = SparkConf()\ .setMaster("local")\ .setAppName("pyspark-unittests")\ .set("spark.sql.parquet.compression.codec", "snappy")\ # 替换成你实际的JAR包路径,多个用逗号分隔 .set("spark.jars", "/path/to/hadoop-aws-2.7.3.jar,/path/to/aws-java-sdk-1.7.4.jar")\ # 如果你没配置本地AWS凭证文件,就填这里(不推荐硬编码) .set("spark.hadoop.fs.s3a.access.key", "你的AWS_ACCESS_KEY_ID")\ .set("spark.hadoop.fs.s3a.secret.key", "你的AWS_SECRET_ACCESS_KEY") sc = SparkContext(conf=conf) # 重点:用s3a://协议,Spark 2.3推荐这个,比老的s3://更稳定 input_rdd = sc.textFile("s3a://your-bucket-name/path/to/your-file.txt") # 测试读取前5行数据 print(input_rdd.take(5))
方式2:通过环境变量加载JAR(更省心)
不想在代码里写JAR路径的话,直接在PyCharm的运行配置里加个环境变量:
- 变量名:
PYSPARK_SUBMIT_ARGS - 变量值:
--jars /path/to/hadoop-aws-2.7.3.jar,/path/to/aws-java-sdk-1.7.4.jar pyspark-shell
这样启动PySpark时会自动加载这些JAR包,代码里就不用再设置spark.jars参数了。
步骤3:安全管理AWS凭证(强烈推荐)
绝对不要把AWS凭证硬编码到代码里!建议用本地凭证文件:
- 在你的用户目录下创建
.aws/credentials文件:- Windows:
C:\Users\你的用户名\.aws\credentials - Linux/macOS:
~/.aws/credentials
- Windows:
- 文件内容按这个格式写:
[default] aws_access_key_id = YOUR_ACCESS_KEY_ID aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
配置好后,Spark会自动读取这个文件,你可以删掉代码里的凭证配置,既安全又省事。
常见坑点排查
- 如果碰到
ClassNotFoundException:大概率是JAR包版本不匹配,一定要确保Hadoop AWS JAR的版本和Spark依赖的Hadoop版本一致(Spark 2.3对应Hadoop 2.7.x)。 - 读取时报权限错误:检查你的AWS凭证有没有对应S3桶的读取权限,或者桶的政策是不是允许这个凭证访问。
- 一定要用
s3a://协议:老的s3://协议在Spark 2.3中已经被弃用,而且需要更多额外依赖,用s3a://更靠谱。
内容的提问来源于stack exchange,提问作者Jared
相关产品推荐
相关产品推荐

