Spring Boot无Spark读取Parquet:本地正常ECS部署报错
问题描述
- 报错信息:
Can not read value at 0 in block -1 in file file: localdirectory/samplefile.parquet - 操作流程:从S3存储桶下载包含Parquet文件的目录到本地,再通过独立Java项目读取文件内容
- 环境差异:本地IntelliJ IDEA中运行完全正常,部署到AWS ECS容器后触发上述读取错误
相关代码片段
S3目录下载代码
MultipleFileDownload multipleFileDownload = transferManager.downloadDirectory(bucketName, keyPrefix, directoryToSaveParquetFiles);
Parquet文件读取代码
Configuration conf = new Configuration(); conf.set("parquet.avro.readInt96AsFixed", "true"); ParquetReader<GenericRecord> reader = AvroParquetReader.<GenericRecord>builder(new Path(filePath)).withConf(conf).build(); GenericRecord obj = reader.read(); while (obj != null) { // 读取属性逻辑 obj = reader.read(); }
导入的依赖类
import com.amazonaws.services.s3.transfer.TransferManager; import com.amazonaws.services.s3.transfer.TransferManagerBuilder; import org.apache.avro.generic.GenericRecord; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.parquet.avro.AvroParquetReader; import org.apache.parquet.hadoop.ParquetReader; import org.apache.commons.io.FileUtils;
使用的SDK版本
Amazon Corretto 11.0.11
排查与解决方法
- 确保文件下载完成后再读取
downloadDirectory是异步操作,ECS环境中可能出现读取逻辑先于下载完成执行的情况,导致读取不完整的文件。添加等待下载完成的逻辑:
multipleFileDownload.waitForCompletion(); if (!multipleFileDownload.isDone() || multipleFileDownload.isFailed()) { throw new RuntimeException("S3目录下载失败,状态:" + multipleFileDownload.getState()); } // 此处再执行Parquet读取逻辑
同时可以验证ECS本地文件的大小、哈希值是否与S3中的源文件一致,确认文件没有损坏或截断。
- 适配Hadoop本地文件系统配置
ECS容器中Hadoop的默认文件系统配置可能异常,显式指定使用本地文件系统:
Configuration conf = new Configuration(); conf.set("fs.defaultFS", "file:///"); // 强制使用本地文件系统 conf.set("parquet.avro.readInt96AsFixed", "true");
避免Hadoop错误地尝试用分布式文件系统协议解析本地文件路径。
- 检查容器内权限设置
- 确认ECS任务执行角色拥有目标S3存储桶的读取权限
- 检查容器内下载目录及文件的权限,确保程序进程有读写访问权限(可在镜像构建或启动脚本中添加
chmod命令调整权限)
- 统一依赖版本
本地开发环境与ECS容器的依赖版本可能存在差异,尤其是Parquet、Avro、Hadoop相关依赖。在pom.xml中锁定所有相关依赖的版本,保证容器构建时使用与本地完全一致的依赖包。
内容的提问来源于stack exchange,提问作者mold_9580
相关产品推荐
相关产品推荐

