[英]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代碼的先前類似問題復制目錄的示例
兩件事情:
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.