所以我试图理解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的范围总是限制在创建输入流时已经写入的那些字节。有没有办法解决?我没有在输入流或类似的东西上看到'refresh()'方法。
如果我有某种方法强制输入流来更新其可用字节,我真的非常喜欢它。我错过了什么?我究竟做错了什么?这样做这样做的方法是错误的吗?
答案 0 :(得分:1)
据我所知,DFSInputStream
仅在打开时刷新其已定位块的列表,并且在尝试从块读取时遇到错误。因此,无论您在输出流中执行什么操作,输入流都不会更新。
如果您正在尝试实施单生产者/多消费者系统,您可能会考虑使用zookeeper之类的东西进行协调。