【发布时间】:2016-08-03 11:32:25
【问题描述】:
我使用的是 Hadoop 2.6,并且我有一个安装了 HDFS 的虚拟机集群。我正在尝试通过在我的本地运行的一些 Java 代码远程读取我的 HDFS 中的文件,以基本方式,使用BufferedReader
FileSystem fs = null;
String hadoopLocalPath = "/path/to/my/hadoop/local/folder/etc/hadoop";
Configuration hConf = new Configuration();
hConf.addResource(new Path(hadoopLocalPath + File.separator + "core-site.xml"));
hConf.addResource(new Path(hadoopLocalPath + File.separator + "hdfs-site.xml"));
try {
fs = FileSystem.get(URI.create("hdfs://10.0.0.1:54310/"), hConf);
} catch (IOException e1) {
e1.printStackTrace();
System.exit(-1);
}
Path startPath = new Path("/user/myuser/path/to/my/file.txt");
FileStatus[] fileStatus;
try {
fileStatus = fs.listStatus(startPath);
Path[] paths = FileUtil.stat2Paths(fileStatus);
for(Path path : paths) {
BufferedReader br=new BufferedReader(new InputStreamReader(fs.open(path)));
String line = new String();
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
程序可以正确访问HDFS(无异常)。如果我要求通过代码列出文件和目录,它可以毫无问题地读取它们。
现在的问题是,如果我尝试读取文件(如代码所示),它会在读取时(在此期间)卡住,直到出现 BlockMissingException
org.apache.hadoop.hdfs.BlockMissingException: Could not obtain block: BP-2005327120-10.1.1.55-1467731650291:blk_1073741836_1015 file=/user/myuser/path/to/my/file.txt
at org.apache.hadoop.hdfs.DFSInputStream.chooseDataNode(DFSInputStream.java:888)
at org.apache.hadoop.hdfs.DFSInputStream.blockSeekTo(DFSInputStream.java:568)
at org.apache.hadoop.hdfs.DFSInputStream.readWithStrategy(DFSInputStream.java:800)
at org.apache.hadoop.hdfs.DFSInputStream.read(DFSInputStream.java:847)
at java.io.DataInputStream.read(DataInputStream.java:149)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at uk.ou.kmi.med.datoolkit.tests.access.HDFSAccessTest.main(HDFSAccessTest.java:55)
我已经知道的:
- 我直接在运行namenode的机器上试了同样的代码,效果很好
- 我已经检查了namenode的日志,并将我本地机器的用户添加到管理HDFS的组中(如this thread和other related threads所建议的那样)
- 正如this thread 所建议的那样,完全限定域名不应该有问题,因为我使用的是静态 IP。另一方面,“您的集群在 VM 中运行并且其对客户端的虚拟化网络访问被阻止”可以是一个选项。我会说,如果是这样,它不应该允许我对 HDFS 执行任何操作(请参阅下一点)
- 集群在有防火墙的网络上运行,并且我已经正确打开并转发了端口 54310(我可以访问 HDFS 用于其他目的,例如创建文件、目录和列出它们的内容)。我想知道文件读取是否需要打开其他端口
【问题讨论】: