簡體   English   中英

使用Java API將數據上傳到HDFS

[英]Upload data to HDFS with Java API

我已經搜索了一段時間,似乎沒有一種解決方案適合我。

非常簡單-我想使用Java API將數據從本地文件系統上傳到HDFS。 Java程序將在已配置為通過外殼與遠程Hadoop群集進行通信的主機(即hdfs dfs -ls等)上運行。

我在項目中包含以下依賴項:

hadoop-core:1.2.1
hadoop-common:2.7.1
hadoop-hdfs:2.7.1

我有如下代碼:

 File localDir = ...;
 File hdfsDir = ...;
 Path localPath = new Path(localDir.getCanonicalPath());
 Path hdfsPath = new Path(hdfsDir.getCanonicalPath());
 Configuration conf = new Configuration();
 conf.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
 conf.set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName());
 Filesystem fs = FileSystem.get(configuration);
 fs.getFromLocalFile(localPath, hdfsPath);

本地數據不會復制到Hadoop集群,但是不會報告任何錯誤,也不會引發任何異常。 我已經為org.apache.hadoop包啟用了TRACE日志記錄。 我看到以下輸出:

 DEBUG Groups:139 -  Creating new Groups object
 DEBUG Groups:139 -  Creating new Groups object
 DEBUG Groups:59 - Group mapping impl=org.apache.hadoop.security.ShellBasedUnixGroupsMapping; cacheTimeout=300000
 DEBUG Groups:59 - Group mapping impl=org.apache.hadoop.security.ShellBasedUnixGroupsMapping; cacheTimeout=300000
 DEBUG UserGroupInformation:147 - hadoop login
 DEBUG UserGroupInformation:147 - hadoop login
 DEBUG UserGroupInformation:96 - hadoop login commit
 DEBUG UserGroupInformation:96 - hadoop login commit
 DEBUG UserGroupInformation:126 - using local user:UnixPrincipal: willra05
 DEBUG UserGroupInformation:126 - using local user:UnixPrincipal: willra05
 DEBUG UserGroupInformation:558 - UGI loginUser:<username_redacted>
 DEBUG UserGroupInformation:558 - UGI loginUser:<username_redacted>
 DEBUG FileSystem:1441 - Creating filesystem for file:///
 DEBUG FileSystem:1441 - Creating filesystem for file:///
 DEBUG FileSystem:1290 - Removing filesystem for file:///
 DEBUG FileSystem:1290 - Removing filesystem for file:///
 DEBUG FileSystem:1290 - Removing filesystem for file:///
 DEBUG FileSystem:1290 - Removing filesystem for file:///

誰能協助我解決這個問題?

編輯1:(2015年9月15日)

我刪除了2個Hadoop依賴項-我現在僅使用一個:

hadoop-core:1.2.1

我的代碼現在如下:

File localDir = ...;
File hdfsDir = ...;
Path localPath = new Path(localDir.getCanonicalPath());
Path hdfsPath = new Path(hdfsDir.getCanonicalPath());
Configuration conf = new Configuration();
fs.getFromLocalFile(localPath, hdfsPath);

我以前使用以下命令執行我的應用程序:

$ java -jar <app_name>.jar <app_arg1> <app_arg2> ...

現在,我使用以下命令執行它:

$ hadoop jar <app_name>.jar <app_arg1> <app_arg2> ...

通過這些更改,我的應用程序現在可以按預期與HDFS交互。 據我所知, hadoop jar命令僅適用於打包為可執行jar的Map Reduce作業,但是這些更改對我來說很成功。

我不確定您要采用的方法,但是下面是使用java libs將數據上傳到hdfs的一種方法:

//imports required 
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;

//some class here .....
Configuration conf = new Configuration();
conf.set("fs.defaultFS", <hdfs write endpoint>);
FileSystem fs = FileSystem.get(conf);
fs.copyFromLocalFile(<src>, <dst>);

另外,如果本地有hadoop conf xml,則可以將它們包括在類路徑中。 然后,hadoop fs詳細信息將在運行時自動獲取,並且您無需設置“ fs.defaultFS”。 另外,如果您在舊的hdfs版本中運行,則可能需要使用“ fs.default.name”而不是“ fs.defaultFS”。 如果不確定hdfs終結點,通常是hdfs namenode url。 這是從本地系統到hdfs Java代碼的先前類似問題復制目錄的示例

兩件事情:

  1. 如果要創建Hadoop客戶端,最好添加hadoop-client依賴項。 它包括所有子模塊所需的依賴關系。 https://github.com/apache/hadoop/blob/2087eaf684d9fb14b5390e21bf17e93ac8fea7f8/hadoop-client/pom.xml 除非擔心Jar的大小,並且您非常確定不會再需要其他依賴項,否則就不要這樣做。
  2. 使用hadoop命令執行作業時,執行的類是RunJar而不是驅動程序類。 然后RunJar執行您的工作。 有關更多詳細信息,請參見以下代碼: https : //github.com/apache/hadoop/blob/2087eaf684d9fb14b5390e21bf17e93ac8fea7f8/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ RunJar.java#L139

如果查看RunJar類中的createClassLoader方法,您會注意到classpath中包含了幾個位置。

然后,如果直接使用java -jar命令執行您的類,則可能會忽略在hadoop jar正在執行的hadoop中執行作業的所有其他必需步驟。

卡薩,您需要使用方法

public static FileSystem get(URI uri,Configuration conf)

要獲取fs ,如果使用java -jar命令,則uri參數是必需的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM