EMR集群Jupyter中PySpark加载parquet文件报Py4JJavaError如何解决
EMR集群Jupyter中PySpark加载Parquet文件报错排查方案
问题背景
在EMR集群的Jupyter Notebook中运行PySpark代码,加载S3或本地Parquet文件时多次触发报错,常规调整方案无效,对应报错场景和完整解决方法如下:
报错场景1:s3协议不支持
执行代码
spark = SparkSession.builder.master("local").appName("app name").config("spark.some.config.option", True).getOrCreate() file = "s3://somelocation" df = spark.read.parquet(file)
核心报错信息
org.apache.hadoop.fs.UnsupportedFileSystemException: No FileSystem for scheme "s3"
报错原因
Spark默认未内置原生s3协议的文件系统实现,且你使用了local运行模式,无法加载EMR集群内置的S3访问依赖。
报错场景2:修改为s3a协议后缺少实现类
执行调整
将路径前缀从s3改为s3a后重新执行加载
核心报错信息
java.lang.ClassNotFoundException: Class org.apache.hadoop.fs.s3a.S3AFileSystem not found
报错原因
Spark运行环境缺少对应版本的hadoop-aws依赖包,无法识别s3a协议的实现类。
报错场景3:本地加载文件传入路径列表类型错误
执行代码
import glob spark = (SparkSession .builder .appName('loss_comfal') .config('spark.executor.memory', '110G') .config('spark.driver.memory', '110G') .config('spark.driver.maxResultSize', '110G') .getOrCreate()) files = glob.glob('data/*') df = spark.read.parquet(files)
核心报错信息
java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.String
报错原因
spark.read.parquet()接收的是多个字符串路径的可变参数,而非Python列表对象,直接传入列表会触发类型转换错误。
完整解决步骤
1. 本地文件加载问题修复
将路径列表解包为可变参数传入即可,修改代码如下:
# 对列表使用*解包 df = spark.read.parquet(*files)
2. S3路径加载问题修复(优先使用EMR原生方案)
EMR集群默认已内置S3访问支持,无需手动引入第三方依赖,按如下方式调整代码即可:
spark = SparkSession.builder \ .master("yarn") # EMR集群建议使用yarn模式,不要使用local模式 .appName("app name") \ .config("spark.hadoop.fs.s3.impl", "com.amazon.ws.emr.hadoop.fs.EmrFileSystem") \ .getOrCreate() # 路径保持s3前缀即可 file = "s3://somelocation" df = spark.read.parquet(file)
3. 额外验证项
- 确认EMR集群的EC2实例角色已经配置了对应S3存储桶的读写权限,无需手动配置AK/SK
- 确认S3路径拼写正确,路径下存在有效Parquet文件
- 如使用yarn模式运行,确认集群剩余资源足够启动对应规格的Executor
内容的提问来源于stack exchange,提问作者Chris_007
相关产品推荐
相关产品推荐

