2

所以我试图了解 HDFS 中的一些行为。我的目标是设置一个配置,在其中我打开一个 FSDataOutputStream 到某个位置,然后我让我的应用程序的其他部分在我写入任何字节之前立即打开一个 FSDataInputStream 到同一位置。

这个想法是,当我将字节写入 FSDataOutputStream、刷新它们并调用“sync()”时,任何可以访问同一位置的 FSDataInputStream 的人都应该能够读取这些字节。

可悲的是,它似乎不是那样工作的。当我以这种方式设置代码时,会发生这种情况:

FSDataOutputStream writer = fs.create(new Path("/foo/bar"));
FSDataInputStream reader = fs.open(new Path("/foo/bar"));
writer.write(new byte[]{1, 1, 1, 1, 1});
writer.flush();
writer.sync();
System.out.println(reader.available()); // writes '0'

然而!当我以这种方式设置我的代码时,会发生这种情况:

FSDataOutputStream writer = fs.create(new Path("/foo/bar"));
writer.write(new byte[] {1, 1, 1, 1, 1});
writer.flush();
writer.sync();
FSDataInputStream reader = fs.open(new Path("/foo/bar"));
System.out.println(reader.available()); // writes '5'

最后,我运行的第三个测试是这样的:

FSDataOutputStream writer = fs.create(new Path("/foo/bar"));
writer.write(new byte[] {1, 1, 1, 1, 1});
writer.flush();
writer.sync();
FSDataInputStream reader = fs.open(new Path("/foo/bar"));
writer.write(new byte[] {2, 2, 2, 2, 2});
writer.flush();
writer.sync();
System.out.println(reader.available()); // writes '5'

我的结论是 FSDataInputStream 的范围总是被限制在创建输入流时已经写入的那些字节。有没有办法解决?我在输入流上看不到“刷新()”方法或类似的东西。

如果我有某种方法可以强制输入流更新其可用字节,我会非常非常喜欢它。我错过了什么?我究竟做错了什么?这仅仅是做这样的事情的错误方法吗?

4

1 回答 1

1

据我所知,DFSInputStream仅在打开时刷新其定位块列表,并且在尝试从块中读取时遇到错误。因此,无论您在输出流中做什么,输入流都不会更新。

如果您正在尝试实现单生产者/多消费者系统,您可能会考虑使用类似 zookeeper 的东西进行协调。

于 2013-05-21T18:58:00.033 回答