我已经搜索了一段时间,但似乎没有任何解决方案对我有用。
非常简单 - 我想使用Java API将数据从本地文件系统上传到HDFS。 Java程序将在已配置为通过shell(即hdfs dfs -ls
等)与远程Hadoop集群通信的主机上运行。
我在项目中包含了以下依赖项:
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集群,但未报告任何错误,也不会引发异常。我已为TRACE
包启用org.apache.hadoop
日志记录。我看到以下输出:
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作业,但这些更改为我做了诀窍。
答案 0 :(得分:1)
我不确定您所遵循的方法,但以下是使用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 xmls,则可以将它们包含在类路径中。然后,hadoop fs详细信息将在运行时自动获取,您无需设置&#34; fs.defaultFS&#34; 。此外,如果您使用的是旧的hdfs版本,则可能需要使用&#34; fs.default.name&#34;而不是&#34; fs.defaultFS&#34;。如果您不确定hdfs端点,通常是hdfs namenode url。以下是之前类似问题copying directory from local system to hdfs java code
的示例答案 1 :(得分:0)
两件事:
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 如果您查看createClassLoader
课程中的RunJar
方法,您会注意到类路径中包含多个位置。
然后,如果您使用 java -jar 命令直接执行您的课程,您可能会忽略在hadoop中执行您的工作所需的所有其他必要步骤 hadoop jar 正在做。
答案 2 :(得分:0)
Kasa,你需要使用方法
public static FileSystem get(URI uri,Configuration conf)
要获得fs
,如果使用java -jar
命令,则必须使用uri参数。