无法从 Windows 连接到远程 HDFS

Posted

技术标签:

【中文标题】无法从 Windows 连接到远程 HDFS【英文标题】:Cannot connect to remote HDFS from Windows 【发布时间】:2015-11-12 21:39:24 【问题描述】:

我正在尝试连接到远程 HDFS 实例

        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://hostName:8020");
        conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
        FileSystem fs = FileSystem.get(conf);
        RemoteIterator<LocatedFileStatus> ri = fs.listFiles(fs.getHomeDirectory(), false);
        while (ri.hasNext()) 
            LocatedFileStatus lfs = ri.next();
            //log.debug(lfs.getPath().toString());
        

        fs.close();

这是我的 Maven 依赖项

<dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-mapreduce-client-core</artifactId>
        <version>2.7.1</version>
    </dependency>

    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>2.7.1</version>
    </dependency>

    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-examples</artifactId>
        <version>1.2.1</version>
    </dependency>

    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-hdfs</artifactId>
        <version>2.7.1</version>
    </dependency>

这是我远程节点上 hadoop version 命令的结果

hadoop version
Hadoop 2.7.1.2.3.0.0-2557

但我明白了

Exception in thread "main" java.lang.UnsupportedOperationException: Not implemented by the DistributedFileSystem FileSystem implementation
at org.apache.hadoop.fs.FileSystem.getScheme(FileSystem.java:217)
at org.apache.hadoop.fs.FileSystem.loadFileSystems(FileSystem.java:2624)
at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2634)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2651)
at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:92)
at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2687)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2669)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:371)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:170)
at filecheck.HdfsTest.main(HdfsTest.java:21)

这是导致错误的行

FileSystem fs = FileSystem.get(conf);

知道为什么会发生这种情况吗?

在尝试了 Manjunath 的回答之后

这就是我得到的

ERROR util.Shell: Failed to locate the winutils binary in the hadoop binary path
java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries.
    at org.apache.hadoop.util.Shell.getQualifiedBinPath(Shell.java:356)
    at org.apache.hadoop.util.Shell.getWinUtilsPath(Shell.java:371)
    at org.apache.hadoop.util.Shell.<clinit>(Shell.java:364)
    at org.apache.hadoop.util.StringUtils.<clinit>(StringUtils.java:80)
    at org.apache.hadoop.fs.FileSystem$Cache$Key.<init>(FileSystem.java:2807)
    at org.apache.hadoop.fs.FileSystem$Cache$Key.<init>(FileSystem.java:2802)
    at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2668)
    at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:371)
    at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:170)
    at filecheck.HdfsTest.main(HdfsTest.java:27)
15/11/16 09:48:23 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Exception in thread "main" java.lang.IllegalArgumentException: Pathname  from hdfs://hostName:8020 is not a valid DFS filename.
    at org.apache.hadoop.hdfs.DistributedFileSystem.getPathName(DistributedFileSystem.java:197)
    at org.apache.hadoop.hdfs.DistributedFileSystem.access$000(DistributedFileSystem.java:106)
    at org.apache.hadoop.hdfs.DistributedFileSystem$DirListingIterator.<init>(DistributedFileSystem.java:940)
    at org.apache.hadoop.hdfs.DistributedFileSystem$DirListingIterator.<init>(DistributedFileSystem.java:927)
    at org.apache.hadoop.hdfs.DistributedFileSystem$19.doCall(DistributedFileSystem.java:872)
    at org.apache.hadoop.hdfs.DistributedFileSystem$19.doCall(DistributedFileSystem.java:868)
    at org.apache.hadoop.fs.FileSystemLinkResolver.resolve(FileSystemLinkResolver.java:81)
    at org.apache.hadoop.hdfs.DistributedFileSystem.listLocatedStatus(DistributedFileSystem.java:886)
    at org.apache.hadoop.fs.FileSystem.listLocatedStatus(FileSystem.java:1694)
    at org.apache.hadoop.fs.FileSystem$6.<init>(FileSystem.java:1787)
    at org.apache.hadoop.fs.FileSystem.listFiles(FileSystem.java:1783)
    at filecheck.HdfsTest.main(HdfsTest.java:29)

【问题讨论】:

你能发布整个堆栈跟踪吗? 我已经添加了堆栈跟踪和导致错误的代码行 【参考方案1】:

我的HDFS客户端代码代码使用hadoop-hdfs还需要:

    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>2.7.1</version>
    </dependency>

我使用 Hortonworks 存储库:

    <repository>
        <id>repo.hortonworks.com</id>
        <name>Hortonworks HDP Maven Repository</name>
        <url>http://repo.hortonworks.com/content/repositories/releases/</url>
    </repository>

我认为您选择了错误的 FileSystem 版本。

【讨论】:

谢谢,但如果我按照你的建议做,我会得到 FileSystem 类型的方法 listFiles(Path, boolean) 是未定义的【参考方案2】:

异常发生在FileSystem.java,在getScheme() 方法中,它只是抛出UnsupportedOperationException 异常。

  public String getScheme() 
    throw new UnsupportedOperationException("Not implemented by the " + getClass().getSimpleName() + " FileSystem implementation");
  

它正在调用FileSystem类的getScheme()方法,而不是从DistributedFileSystem类调用getScheme()方法。

DistributedFileSystem 类的getScheme() 方法返回:

@Override
  public String getScheme() 
    return HdfsConstants.HDFS_URI_SCHEME;
  

所以,要克服这个问题,需要修改“FileSystem.get(conf)”语句,如下图:

DistributedFileSystem fs = (DistributedFileSystem) FileSystem.get(conf);

编辑:

我试用了这个程序,它对我来说非常好用。事实上,它可以在有和没有强制转换的情况下工作。 以下是我的代码(唯一的区别是,我将递归列表设置为“true”):

package com.hadooptests;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.apache.hadoop.hdfs.DistributedFileSystem;

import java.io.IOException;

public class HDFSConnect 
    public static void main(String[] args)
    
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://machine:8020");
        conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
        DistributedFileSystem fs = null;
        try 
            fs = (DistributedFileSystem) FileSystem.get(conf);
            RemoteIterator<LocatedFileStatus> ri;
            ri = fs.listFiles(new Path("hdfs://machine:8020/"), true);
            while (ri.hasNext()) 
                LocatedFileStatus lfs = ri.next();
                System.out.println(lfs.getPath().toString());
            
            fs.close();

         catch (IOException e) 
            e.printStackTrace();
        
    

我的专家:

<dependencies>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-hdfs</artifactId>
        <version>2.7.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>2.7.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-core</artifactId>
        <version>1.2.1</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <archive>
                    <manifest> 
                      <mainClass>com.hadooptests.HDFSConnect
                    </mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

我将程序运行为:

java -cp "%CLASSPATH%;hadooptests-1.0-SNAPSHOT.jar" com.hadooptests.HDFSConnect

其中 CLASSPATH 设置为: .;%HADOOP_HOME%\etc\hadoop\;%HADOOP_HOME%\share\hadoop\common\*;%HADOOP_HOME%\share\hadoop\common\lib\*;%HADOOP_HOME%\share\hadoop\hdfs\*;%HADOOP_HOME%\share\hadoop\hdfs\lib\*;%HADOOP_HOME%\share\hadoop\mapreduce\*;%HADOOP_HOME%\share\hadoop\mapreduce\lib\*;%HADOOP_HOME%\share\hadoop\tools\*;%HADOOP_HOME%\share\hadoop\tools\lib\*;%HADOOP_HOME%\share\hadoop\yarn\*;%HADOOP_HOME%\share\hadoop\yarn\lib\*

一些输出,我得到了:

hdfs://machine:8020/app-logs/machine/logs/application_1439815019232_0001/machine.corp.com_45454
hdfs://machine:8020/app-logs/machine/logs/application_1439815019232_0002/machine.corp.com_45454
hdfs://machine:8020/app-logs/machine/logs/application_1439817471006_0002/machine.corp.com_45454
hdfs://machine:8020/app-logs/machine/logs/application_1439817471006_0003/machine.corp.com_45454

编辑 2:

我的环境:

Windows 上的 Hadoop 2.7.1。

我安装了 HDP 2.3.0,它部署了 Hadoop 2.7.1

【讨论】:

我已经更新了答案。查看。它对我来说很好。 谢谢,我会检查并确认。顺便说一句,我正在从 eclipse 运行程序,我没有通过 java -jar 命令执行它。这会有所作为吗? 不确定。我从未使用过 Eclipse。 请注意,我正在从 Windows 运行此代码,但我正在尝试连接到在 linux 机器上运行的远程 hdfs 实例 是的,我在 Windows 上。

以上是关于无法从 Windows 连接到远程 HDFS的主要内容,如果未能解决你的问题,请参考以下文章