我已经找了一段时间了,似乎没有一个解决办法对我有效。
非常简单-我想使用JavaAPI将数据从本地文件系统上传到hdfs。java程序将在配置为通过shell与远程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集群,但是没有报告错误,也没有抛出异常。我已经启用了 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:(09/15/2015)
我已经删除了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作业,但这些更改对我起到了作用。
3条答案
按热度按时间4xy9mtcn1#
两件事:
如果要创建hadoop客户机,最好添加hadoop客户机依赖项。它包括所有子模块所需的依赖关系。https://github.com/apache/hadoop/blob/2087eaf684d9fb14b5390e21bf17e93ac8fea7f8/hadoop-client/pom.xml. 除非jar的大小是一个问题,并且您非常确定不需要另一个依赖项。
执行作业时使用
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中执行hadoopjar正在执行的作业所需的所有其他步骤。
ac1kyiln2#
卡萨,你得用这个方法
得到
fs
,如果使用java -jar
命令。vof42yt13#
我不确定您所采用的方法,但下面是使用java libs将数据上载到hdfs的一种方法:
另外,如果您在本地有hadoop conf xml,那么可以将它们包含在类路径中。然后hadoopfs细节将在运行时自动获取,您不需要设置“fs.defaultfs”。另外,如果您运行的是旧的hdfs版本,那么可能需要使用“fs.default.name”而不是“fs.defaultfs”。如果您不确定hdfs端点,则通常是hdfs namenode url。下面是前面类似问题中的一个例子:将目录从本地系统复制到hdfs java代码