我试图使用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();
}
}
我在谷歌上搜索了一下,但没有得到答案。有什么想法吗?提前谢谢。
更新:
- 这是一个java应用程序,我的本地笔记本电脑没有安装Hadoop
- 我有以下依赖项
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);