无法保存到 S3,并出现错误"java.io.IOException: No FileSystem for scheme: s3a"



我试图使用Java将一些测试数据从本地笔记本电脑保存到S3,结果出现以下错误:

java.io.io异常:方案s3a没有文件系统网址:org.apache.hadop.fs.FileSystem.createFileSystem(FileSystem.java:1443(网址:org.apache.hoop.fs.FileSystem.access$200(FileSystem.java:67(网址:org.apache.hoop.fs.FileSystem$Cache.get(FileSystem.java:1464(网址:org.apache.hoop.fs.FileSystem.get(FileSystem.java:263(网址:org.apache.hoop.fs.Path.getFileSystem(Path.java:187(网址:org.apache.parquet.hadoop.ParquetFileWriter。(ParquetFileWriter.java:209(网址:org.apache.parquet.hadoop.ParquetWriter。(ParquetWriter.java:266(网址:org.apache.parquet.hadoop.ParquetWriter$Builder.build(ParquetWriter.java:489(

下面是我的代码

private void testSaveToS3(SysS3Configuration s3Configuration) {
try {
Schema avroSchema = TestDTO.getClassSchema();

Path path = new Path("s3a://" + s3Configuration.getBucketName()+"/test.parquet");


Configuration config = new Configuration();
config.set("fs.s3a.access.key", s3Configuration.getAccessKeyId());
config.set("fs.s3a.secret.key", s3Configuration.getSecretKey());

ParquetWriter writer = AvroParquetWriter.<GenericData.Record>builder(path)
.withSchema(avroSchema)
.withConf(config)
.withCompressionCodec(CompressionCodecName.SNAPPY)
.withWriteMode(ParquetFileWriter.Mode.OVERWRITE)
.build();

List<TestDTO> list = new ArrayList<>();
TestDTO l1 = new TestDTO();
l1.setId(1);
l1.setValue(11);

TestDTO l2 = new TestDTO();
l2.setId(2);
l2.setValue(22);

list.add(l1);
list.add(l2);

for (TestDTO d : list) {
final GenericRecord record = new GenericData.Record(avroSchema);
record.put("id", d.getId());
record.put("value", d.getValue());
writer.write(record);
}

writer.close();

} catch (Exception e) {

e.printStackTrace();
}
}

我在谷歌上搜索了一下,但没有得到答案。有什么想法吗?提前谢谢。

更新:

  1. 这是一个java应用程序,我的本地笔记本电脑没有安装Hadoop
  2. 我有以下依赖项
compile 'com.amazonaws:aws-java-sdk:1.11.747'
compile 'org.apache.parquet:parquet-avro:1.8.1'
compile 'org.apache.hadoop:hadoop-aws:3.3.0'

UPDATE:我按照建议将hadoop-aws版本更改为3.3.0,但仍然得到相同的错误

java.io.IOException: No FileSystem for scheme: s3a
at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2421)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2428)
......

然后我试着改变";s3a://";在我的路径字符串中;s3n://";。现在,我得到一个不同的错误

java.io.IOException: The s3n:// client to Amazon S3 is no longer available: please migrate to the s3a:// client
at org.apache.hadoop.fs.s3native.NativeS3FileSystem.initialize(NativeS3FileSystem.java:82)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2433)

有什么想法吗?伙计们。

首先要检查的是依赖关系,s3文件系统实现与hadoop的其余部分在一个单独的工件中。例如在gradle语法中:

api("org.apache.hadoop:hadoop-aws:$hadoopVersion")

更新:由于添加了依赖项,hadoop 1.2.1版本非常旧,截至2020年8月的当前版本为3.3.0。在旧版本中,您可能可以使用带有s3://s3n://前缀的s3,但您应该真正进行更新,因为较新的s3a实现包含了许多改进。

在配置中添加此项对我有效。

conf.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem");

我在build.gradle中从s3 读取镶木地板文件的依赖项

compile 'org.slf4j:slf4j-api:1.7.5'
compile 'org.slf4j:slf4j-log4j12:1.7.5'
compile 'org.apache.parquet:parquet-avro:1.12.0'
compile 'org.apache.avro:avro:1.10.2'
compile 'com.google.guava:guava:11.0.2'
compile 'org.apache.hadoop:hadoop-client:2.4.0'
compile 'org.apache.hadoop:hadoop-aws:3.3.0'   
compile 'org.apache.hadoop:hadoop-common:3.3.0'      
compile 'com.amazonaws:aws-java-sdk-core:1.11.563'
compile 'com.amazonaws:aws-java-sdk-s3:1.11.563'

如果你有一些带有Date和byte[]的数据,你还需要在配置中添加它

conf.setBoolean(org.apache.parquet.avro.AvroReadSupport.READ_INT96_AS_FIXED, true);

相关内容

最新更新