无法通过 Java API 访问 HDFS (Cloudera-CDH4.4.0)

Can't access HDFS via Java API (Cloudera-CDH4.4.0)

我正在尝试使用 Java 代码访问我的 HDFS,但我无法让它工作...经过 2 天的努力,我认为是时候寻求帮助了。

这是我的代码:

Configuration conf = new Configuration();           
conf.addResource(new Path("/HADOOP_HOME/conf/core-site.xml"));
conf.addResource(new Path("/HADOOP_HOME/conf/hdfs-site.xml"));
FileSystem hdfs = FileSystem.get(conf);

boolean success = hdfs.mkdirs(new Path("/user/cloudera/testdirectory"));
System.out.println(success);
        

我从 here and here 那里得到了这段代码。 不幸的是,hdfs 对象只是一个“LocalFileSystem”对象,所以一定有问题。看起来这正是 Rejeev 在他的网站上写的:

[...] If you do not assign the configurations to conf object (using hadoop xml file) your HDFS operation will be performed on the local file system and not on the HDFS. [...]

使用绝对路径我得到相同的结果。

conf.addResource(new Path("/etc/hadoop/conf/core-site.xml"))

这是我目前使用的库:

hadoop-core-2.0.0-mr1-cdh4.4.0.jar

我听说 hadoop-core 被拆分成多个库,所以我也尝试了以下库:

hadoop-common-2.0.0-alpha.jar

hadoop-mapreduce-client-core-2.0.2-alpha.jar

我正在使用 Cloudera-CDH4.4.0,因此已经安装了 hadoop。通过控制台一切正常。 例如:

hadoop fs -mkdir testdirectory

所以一切都应该按照默认设置正确。

我希望你们能帮助我...这东西快把我逼疯了!如此简单的任务却失败了,真是令人沮丧。

非常感谢您的帮助。

试试这个:

conf.set("fs.defaultFS", "file:///"); conf.set("mapreduce.framework.name", "local");

1) 你不需要 conf.addResource 除非你覆盖任何配置变量。

2) 希望您在命令 window 而不是在 eclipse 中创建 Jar 文件和 运行 jar 文件。 如果你在 eclipse 中执行,它将在本地文件系统上执行。

3) 我 运行 下面的代码成功了。

public class Hmkdirs {
public static void main(String[] args) 
        throws IOException 
        { 
Configuration conf = new Configuration();  
FileSystem fs = FileSystem.get(conf); 
boolean success = fs.mkdirs(new Path("/user/cloudera/testdirectory1"));
System.out.println(success);
        }

}

4) 要执行,您需要创建一个 jar 文件,您可以从 eclipse 或命令提示符执行此操作 并执行jar文件。

命令提示符 jar 文件示例:

javac -classpath /usr/local/hadoop/hadoop-core-1.2.1.jar:/usr/local/hadoop/lib/commons-cli-1.2.jar -d classes WordCount.java && jar -cvf WordCount.jar -C classes/ .

在命令提示符下通过 hadoop 执行 jar 文件。

hadoop jar hadoopfile.jar hadoop.sample.fileaccess.Hmkdirs

hadoop.sample.fileaccess 是我的 class Hmkdirs 所在的包。如果您的 class 存在于默认包中,则无需指定它,只需 class 即可。


更新:您可以从 eclipse 执行并仍然访问 hdfs,检查下面的代码。

public class HmkdirsFromEclipse {

public static void main(String[] args) 

        throws IOException 
        { 
Configuration conf = new Configuration();  
conf.addResource("/etc/hadoop/conf/core-site.xml");
conf.addResource("/etc/hadoop/conf/hdfs-site.xml");
conf.set("fs.defaultFS", "hdfs://quickstart.cloudera:8020/");
conf.set("hadoop.job.ugi", "cloudera");
conf.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
FileSystem fs = FileSystem.get(conf); 
boolean success = fs.mkdirs(new Path("/user/cloudera/testdirectory9"));
System.out.println(success);
        }

}

这确实是一个棘手的配置,但这基本上是您需要做的:

    Configuration conf = new Configuration();
    conf.addResource("/etc/hadoop/conf/core-site.xml");
    conf.addResource("/etc/hadoop/conf/hdfs-site.xml");
    conf.set("fs.defaultFS", hdfs://[your namenode]);
    conf.set("hadoop.job.ugi", [your user]
    conf.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());

确保你的类路径中也有 hadoop-hdfs。