无法从 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的主要内容,如果未能解决你的问题,请参考以下文章

无法从 Windows 和 Linux (CentOS7) 连接到我的远程 MySQL 服务器

无法从 Mac lion 连接到远程 mysql

无法从 Vista x64 Windows 服务连接到 SQL Server 2005 Db

“无法连接到远程 VM”将 jdb 连接到 Windows 上的 android 模拟器

无法从远程计算机上的 mysql 工作台连接到 phpmyadmin 或数据库

windows远程桌面之前用于连接到xxx的凭据无法工作