【问题标题】:BlockMissingException while remotely reading HDFS file from Java in Hadoop 2在 Hadoop 2 中从 Java 远程读取 HDFS 文件时出现 BlockMissingException
【发布时间】: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 threadother related threads所建议的那样)
  • 正如this thread 所建议的那样,完全限定域名不应该有问题,因为我使用的是静态 IP。另一方面,“您的集群在 VM 中运行并且其对客户端的虚拟化网络访问被阻止”可以是一个选项。我会说,如果是这样,它不应该允许我对 HDFS 执行任何操作(请参阅下一点)
  • 集群在有防火墙的网络上运行,并且我已经正确打开并转发了端口 54310(我可以访问 HDFS 用于其他目的,例如创建文件、目录和列出它们的内容)。我想知道文件读取是否需要打开其他端口

【问题讨论】:

    标签: java hadoop


    【解决方案1】:

    你能确保 Datanode 也可以从客户端访问吗?连接在 AWS 中配置的 Hadoop 时,我遇到了类似的问题。我可以通过在所有数据节点和我的客户端系统之间建立连接来解决这个问题

    【讨论】:

    • 这可能是问题所在:所有虚拟机所连接的网络都由一个访问点管理,该访问点控制访问。当然,它通过防火墙和端口转发机制对访问施加限制,禁止我的客户端访问 Datanode。 Namenode 是可访问的,因为我打开并转发了端口 54310 到 Namenode。我只能通过接入点连接到网络。现在我想知道如何使 Datanodes 可访问。
    • 您可以尝试在 hdfs-default.xml 中跨步 dfs.datanode.address 并尝试从客户端进行 SSH 转发。 hadoop.apache.org/docs/r2.4.1/hadoop-project-dist/hadoop-hdfs/…
    • 好的,我想我必须更改我的数据节点的hdfs-site.xml,指定选项dfs.datanodes.addressdfs.datanodes.ipc.addressdfs.datanodes.http.addressdfs.datanodes.https.address,为每个数据节点设置不同的端口,然后在我的接入点中转发该端口。对吗?
    • 抱歉,正在同时发表评论
    • 所以,我有两个数据节点,dn1dn2。我通过dfs.datanodes.address 选项在每个hdfs-site.xml 中添加了一个特定端口,分别是0.0.0.0:500110.0.0.0:50012。我重新启动了 HDFS。我在防火墙上打开了公共端口50011和50012,并将公共端口50011转发到dn1的50011端口,将公共端口50012转发到dn2的50012端口。仍然没有工作,但我觉得我很接近。怎么了?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多