为什么 hsync() 不刷新我的 hdfs 文件?
Why is hsync() not flushing my hdfs file?
尽管有关于这个主题的所有资源,但我在刷新磁盘上的 hdfs 文件时遇到问题 (hadoop 2.6)
调用 FSDataOutputStream.hsync()
应该可以解决问题,但由于未知原因,它实际上只能使用一次...
这是一个失败的简单单元测试:
@Test
public void test() throws InterruptedException, IOException {
final FileSystem filesys = HdfsTools.getFileSystem();
final Path file = new Path("myHdfsFile");
try (final FSDataOutputStream stream = filesys.create(file)) {
Assert.assertEquals(0, getSize(filesys, file));
stream.writeBytes("0123456789");
stream.hsync();
stream.hflush();
stream.flush();
Thread.sleep(100);
Assert.assertEquals(10, getSize(filesys, file)); // Works
stream.writeBytes("0123456789");
stream.hsync();
stream.hflush();
stream.flush();
Thread.sleep(100);
Assert.assertEquals(20, getSize(filesys, file)); // Fails, still 10
}
Assert.assertEquals(20, getSize(filesys, file)); // works
}
private long getSize(FileSystem filesys, Path file) throws IOException {
return filesys.getFileStatus(file).getLen();
}
知道为什么吗?
事实上,hsync()
在内部调用没有标志的私有flushOrSync(boolean isSync, EnumSet<SyncFlag> syncFlags)
,如果提供SyncFlag.UPDATE_LENGTH
,长度只会在namenode上更新。
在上面的测试中,用实际读取文件的代码替换 getSize()
。
private long getSize(FileSystem filesys, Path file) throws IOException {
long length = 0;
try (final FSDataInputStream input = filesys.open(file)) {
while (input.read() >= 0) {
length++;
}
}
return length;
}
要更新大小,您也可以调用(没有适当的 class 类型检查):
((DFSOutputStream) stream.getWrappedStream())).hsync(EnumSet.of(SyncFlag.UPDATE_LENGTH));
尽管有关于这个主题的所有资源,但我在刷新磁盘上的 hdfs 文件时遇到问题 (hadoop 2.6)
调用 FSDataOutputStream.hsync()
应该可以解决问题,但由于未知原因,它实际上只能使用一次...
这是一个失败的简单单元测试:
@Test
public void test() throws InterruptedException, IOException {
final FileSystem filesys = HdfsTools.getFileSystem();
final Path file = new Path("myHdfsFile");
try (final FSDataOutputStream stream = filesys.create(file)) {
Assert.assertEquals(0, getSize(filesys, file));
stream.writeBytes("0123456789");
stream.hsync();
stream.hflush();
stream.flush();
Thread.sleep(100);
Assert.assertEquals(10, getSize(filesys, file)); // Works
stream.writeBytes("0123456789");
stream.hsync();
stream.hflush();
stream.flush();
Thread.sleep(100);
Assert.assertEquals(20, getSize(filesys, file)); // Fails, still 10
}
Assert.assertEquals(20, getSize(filesys, file)); // works
}
private long getSize(FileSystem filesys, Path file) throws IOException {
return filesys.getFileStatus(file).getLen();
}
知道为什么吗?
事实上,hsync()
在内部调用没有标志的私有flushOrSync(boolean isSync, EnumSet<SyncFlag> syncFlags)
,如果提供SyncFlag.UPDATE_LENGTH
,长度只会在namenode上更新。
在上面的测试中,用实际读取文件的代码替换 getSize()
。
private long getSize(FileSystem filesys, Path file) throws IOException {
long length = 0;
try (final FSDataInputStream input = filesys.open(file)) {
while (input.read() >= 0) {
length++;
}
}
return length;
}
要更新大小,您也可以调用(没有适当的 class 类型检查):
((DFSOutputStream) stream.getWrappedStream())).hsync(EnumSet.of(SyncFlag.UPDATE_LENGTH));