2015-01-06 31 views
2

我試圖訪問我的HDFS使用Java代碼,但我無法得到它的工作......經過兩天的掙扎我認爲是時候請求幫忙。無法通過Java API訪問HDFS(Cloudera-CDH4.4.0)

這是我的代碼:

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); 

我得到這個代碼herehere。 不幸的是,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")) 

這是我目前使用的libary:

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

聽說Hadoop的核心被分爲多個庫,所以我也嘗試了以下庫:

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 

所以一切都應該被正確地按照默認設置。

我希望你們能幫助我...這東西讓我瘋狂!以這麼簡單的任務失敗是非常令人沮喪的。

非常感謝您的任何幫助。

回答

0

1),除非你將覆蓋任何配置變量,你並不需要conf.addResource。

2)希望你正在創建一個jar文件,並在命令窗口中運行jar文件,而不是在eclipse中。 如果你在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文件,你可以做到這一點無論是從月食或命令提示符 和執行的jar文件。

命令提示jar文件樣品:

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

在命令提示符下通過hadoop執行jar文件。

Hadoop的罐子hadoopfile.jar hadoop.sample.fileaccess.Hmkdirs

hadoop.sample.fileaccess是在我的課Hmkdirs存在的包。如果您的類存在於默認包中,則不必指定它,只要該類沒有問題。


更新:您可以從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); 
     } 

}

+0

非常感謝您的回覆! :)我跟着你的步驟1-4,通過控制檯用「hadoop jar hadoopfile.jar hadoop.sample.fileaccess.Hmkdirs」執行應用程序,然後控制檯顯示「True」,並創建HDFS中的新文件夾。我想問題是我沒有使用「哈託普罐」。但是,在eclipse中運行代碼時,我得到以下錯誤:java.lang.NoClassDefFoundError:org/apache/commons/logging/LogFactory。你是如何得到這個工作的?你在用什麼庫?再次感謝:) – Tim

+0

加入以下進口: import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; 檢查你的構建路徑下面有jar文件: hadoop-hdfs和hadoop-common – user1652210

1

試試這個:

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

+0

這不提供問題的答案。要批評或要求作者澄清,在他們的帖子下留下評論 - 你總是可以評論你自己的帖子,一旦你有足夠的[聲譽](http://stackoverflow.com/help/whats-reputation),你會能夠[評論任何帖子](http://stackoverflow.com/help/privileges/comment)。 – Ben

+0

Ben爲什麼這不是答案? – Hajmola

+0

這沒有奏效。 – Tim

0

這確實是配置的一個棘手的一點,但是這基本上是你需要做的:

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()); 

確保你在classpath有Hadoop的HDFS,太。

+0

Erik,謝謝你的回覆。當我通過「hadoop jar」從控制檯運行它時,該代碼適用於我,正如user1652210所描述的那樣。你可以從eclipse運行代碼嗎?您使用的是唯一一個hadoop-hdfs庫嗎?從eclipse運行代碼時,我得到了幾個NoClassDefFoundErrors。 – Tim

+0

您至少需要hadoop-hdfs和hadoop-common。請注意,CDH4和CDH5之間的庫名稱已更改。你也應該使用Maven或Gradle來組裝你的類路徑以獲取傳遞依賴關係。 –