【发布时间】:2021-10-30 07:41:33
【问题描述】:
我正在使用 Hadoop GCS Connector 3-2.2.2 和 google-cloud-storage version 1.113.14 将数据写入 Google Cloud Storage 上的文件。
我有一个文件类,它有一个 write 方法,它使用 hadoop 类返回一个 OutputStream,如下所示:
protected FileSystem fs;
protected Path path;
public File(String path) {
this.path = new Path(path);
Configuration conf = new Configuration();
conf.set("fs.defaultFS", fsURL);
conf.setBoolean("dfs.support.append", true);
conf.setInt("ipc.client.connect.max.retries.on.timeouts", 2);
this.fs = FileSystem.newInstance(conf);
}
@Override
public OutputStream write(boolean overwriteIfExists) throws IOException {
return fs.create(path, overwriteIfExists);
}
fs 是 org.apache.hadoop.fs.FileSystem 的实例; path 是 import org.apache.hadoop.fs.Path 的实例;
我什至尝试使用google cloud storage sdk来实现我的write方法:
@Override
public OutputStream write(boolean overwriteIfExists, boolean create) throws IOException {
if (!overwriteIfExists && exists()) {
throw new IOException("File already exists");
}
if (overwriteIfExists && exists()) {
delete();
} // If will write it will mean a new file
BlobId blobId = BlobId.of(bucketName, objectName);
BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build();
WriteChannel writeChannel = storage.writer(blobInfo);
writeChannel.setChunkSize(64 * 1024 * 1024);
return Channels.newOutputStream(writeChannel);
}
我的应用程序的其他部分可以创建我的 File 类的实例并写入 OutputStream,下面是如何测试/模拟写入的示例:
public void write() {
try {
File file = File.newInstance("dir/someFileName");
try (DataOutputStream os = new DataOutputStream(new BufferedOutputStream(file.write(true), this.bufferSize))) {
long i;
for (i = 0L; i < 4096; i++) {
os.write(String.format("some arbitrary string %d\n", new Object[] { Long.valueOf(i) }).getBytes());
}
} catch (Throwable t) {
System.out.println("Couldn't write file");
}
} catch (IOException e) {
System.out.println("Couldn't write file");
}
}
当我使用gsutil ls dir/ 检查写入的文件后,我希望只找到我刚刚创建的 1 个文件,但我得到了 2 个应该被删除的额外临时文件(具有 GCS_SYNCABLE_TEMPFILE 前缀)
gs://dir/_GCS_SYNCABLE_TEMPFILE_someFileName.txt.0.24fccb78-8cea-45fd-852d-ed9385e4246b gs://dir/_GCS_SYNCABLE_TEMPFILE_someFileName.txt.0.cf132710-9d71-4939-a5d8-02b0279cdf3c gs://dir/someFileName.txt
我需要做一些配置吗?或者为什么这些临时文件没有被删除?
或者这可能是任何相关 jar 中的不兼容?我正在使用以下版本的 google 相关依赖项:
- 组:'org.apache.hadoop',名称:'hadoop-common',版本:'3.2.0'
- 组:'org.apache.hadoop',名称:'hadoop-hdfs',版本:'3.2.0'
- 组:'org.apache.hadoop',名称:'hadoop-hdfs-client',版本:'3.2.0'
- 组:“com.google.cloud.bigdataoss”,名称:“gcs-connector”,版本: ‘hadoop3-2.2.2’
- 组:“com.google.api-client”,名称: ‘google-api-client’,版本:‘1.31.3’
- 组:“com.google.cloud”, 名称:“google-cloud-core”,版本:“1.93.4”
- 组: ‘com.google.cloud’,名称:‘google-cloud-core-http’,版本:‘1.93.4’
- 组:“com.google.cloud”,名称:“google-cloud-storage”,版本: ‘1.106.0’
- 组:“com.google.http-client”,名称: ‘google-http-client’,版本:‘1.38.0’
- 组: 'com.google.http-client',名称:'google-http-client-jackson2', 版本:‘1.38.0’
【问题讨论】:
-
"出于性能原因,临时文件的删除是异步发生的,但是在 close() 时会等待进行中的删除,因此只要所有输出流都关闭,就不应该有剩余的进行中的工作发生在这个线程池中”..我的问题是:您在代码中的哪个位置关闭了输出流?我相信如果没有这样配置,临时文件可能不会被删除。
-
如果您还没有关闭输出流,请尝试按照GitHub link 进行操作。如果问题仍然存在,请告诉我。
-
@PriyashreeBhadra 所有 OutputStreams 都实现了AutoCloseable,并且由于我在 try-with-resources 语句中打开输出流,因此在代码完成后会自动调用其自动 close()。所以应该关闭流,为什么这不反映/或文件没有被删除。如果不这样配置,你是什么意思?
-
@PriyashreeBhadra 你对这个 GitHub 链接有什么建议?
-
@PriyashreeBhadra 您还有其他想法吗?这可能是什么问题?或者如何处理?
标签: java hadoop google-cloud-platform google-cloud-dataproc