首页 文章

使用Java API将数据上载到HDFS

提问于
浏览
1

我现在已经搜索了一段时间,似乎没有一个解决方案适合我 .

非常简单 - 我想使用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集群,但未报告任何错误,也不会引发异常 . 我为 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:///

任何人都可以帮助我解决这个问题吗?

EDIT 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 回答

  • 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详细信息将在运行时自动获取,您无需设置"fs.defaultFS" . 此外,如果您在旧的hdfs版本中运行,则可能需要使用"fs.default.name"而不是"fs.defaultFS" . 如果您不确定hdfs endpoints ,通常是hdfs namenode url . 这是以前类似问题的例子copying directory from local system to hdfs java code

  • 0

    两件事情:

    如果您查看 RunJar 类中的 createClassLoader 方法,您会注意到 classpath 中包含多个位置 .

    然后,如果您使用 java -jar 命令直接执行您的类,您可能会忽略在 hadoop jar 正在执行的hadoop中执行作业的所有其他必需步骤 .

  • 0

    卡萨,你需要使用这个方法

    public static FileSystem get(URI uri,Configuration conf)
    

    要获得 fs ,如果使用 java -jar 命令,则必须使用uri参数 .

相关问题