【问题标题】:Not able to append to existing file to HDFS无法将现有文件附加到 HDFS
【发布时间】:2014-03-19 19:45:15
【问题描述】:

我在 VM 上运行单节点 Hadoop 1.2.1 集群。

我的 hdfs-site.xml 看起来像这样:

<configuration>
<property>
  <name>dfs.replication</name>
  <value>1</value>
  <description>Default block replication.
 </description>
</property>
<property>
  <name>dfs.support.append</name>
  <value>true</value>
  <description>Does HDFS allow appends to files?
  </description>
</property>
</configuration>

现在,当我尝试从 Eclipse 运行以下代码时,它总是返回 false:

Configuration config = new Configuration();
    config.set("mapred.job.tracker","10.0.0.6:54311");
    config.set("fs.default.name","hdfs://10.0.0.6:54310");
    FileSystem fs = FileSystem.get(config);
    boolean flag = Boolean.getBoolean(fs.getConf().get("dfs.support.append"));
    System.out.println("dfs.support.append is set to be " + flag);

现在如果我尝试追加到现有文件,我会收到以下错误:

org.apache.hadoop.ipc.RemoteException: java.io.IOException: Append is not supported. Please see the dfs.support.append configuration parameter
    at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.appendFile(FSNamesystem.java:1781)
    at org.apache.hadoop.hdfs.server.namenode.NameNode.append(NameNode.java:725)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:587)
    at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1432)
    at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1428)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:415)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1190)
    at org.apache.hadoop.ipc.Server$Handler.run(Server.java:1426)

    at org.apache.hadoop.ipc.Client.call(Client.java:1113)
    at org.apache.hadoop.ipc.RPC$Invoker.invoke(RPC.java:229)
    at com.sun.proxy.$Proxy1.append(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:85)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:62)
    at com.sun.proxy.$Proxy1.append(Unknown Source)
    at org.apache.hadoop.hdfs.DFSClient.append(DFSClient.java:933)
    at org.apache.hadoop.hdfs.DFSClient.append(DFSClient.java:922)
    at org.apache.hadoop.hdfs.DistributedFileSystem.append(DistributedFileSystem.java:196)
    at org.apache.hadoop.fs.FileSystem.append(FileSystem.java:659)
    at com.vanilla.hadoop.AppendToHdfsFile.main(AppendToHdfsFile.java:29)

怎么了?我错过了什么吗?

【问题讨论】:

    标签: hadoop bigdata


    【解决方案1】:

    您应该尝试使用 2.X.X 版本或 0.2X 版本,因为在 hadoop 0.20.2 之后在 hdfs 上附加了一个文件。在herehere 上查看更多信息

    【讨论】:

      【解决方案2】:

      自 1.0.3 起不支持附加。无论如何,如果你真的需要以前的功能,打开附加功能将标志“dfs.support.broken.append”设置为true。

      hadoop.apache.org/docs/r1.2.1/releasenotes.html

      【讨论】:

        【解决方案3】:

        现在开始配置文件系统:

        public FileSystem configureFileSystem(String coreSitePath, String hdfsSitePath) {
            FileSystem fileSystem = null;
            try {
                Configuration conf = new Configuration();
                conf.setBoolean("dfs.support.append", true);
                Path coreSite = new Path(coreSitePath);
                Path hdfsSite = new Path(hdfsSitePath);
                conf.addResource(coreSite);
                conf.addResource(hdfsSite);
                fileSystem = FileSystem.get(conf);
            } catch (IOException ex) {
                System.out.println("Error occurred while configuring FileSystem");
            }
            return fileSystem;
        }
        

        确保 hdfs-site.xml 中的属性 dfs.support.append 设置为 true。

        您可以通过编辑 hdfs-site.xml 文件手动设置它,也可以通过编程使用:

        conf.setBoolean("dfs.support.append", true);

        让我们从追加到 HDFS 中的文件开始。

        public String appendToFile(FileSystem fileSystem, String content, String dest) throws IOException {
            Path destPath = new Path(dest);
            if (!fileSystem.exists(destPath)) {
                System.err.println("File doesn't exist");
                return "Failure";
            }
            Boolean isAppendable = Boolean.valueOf(fileSystem.getConf().get("dfs.support.append"));
            if(isAppendable) {
                FSDataOutputStream fs_append = fileSystem.append(destPath);
                PrintWriter writer = new PrintWriter(fs_append);
                writer.append(content);
                writer.flush();
                fs_append.hflush();
                writer.close();
                fs_append.close();
                return "Success";
            }
            else {
                System.err.println("Please set the dfs.support.append property to true");
                return "Failure";
            }
        }
        

        要查看数据是否已正确写入 HDFS,让我们编写一个方法从 HDFS 读取并将内容作为字符串返回。

        public String readFromHdfs(FileSystem fileSystem, String hdfsFilePath) {
            Path hdfsPath = new Path(hdfsFilePath);
            StringBuilder fileContent = new StringBuilder("");
            try{
                BufferedReader bfr=new BufferedReader(new InputStreamReader(fileSystem.open(hdfsPath)));
                String str;
                while ((str = bfr.readLine()) != null) {
                    fileContent.append(str+"\n");
                }
            }
            catch (IOException ex){
                System.out.println("----------Could not read from HDFS---------\n");
            }
            return fileContent.toString();
        }
        

        之后,我们就成功地在 HDFS 中写入和读取了文件。是时候关闭文件系统了。

        public void closeFileSystem(FileSystem fileSystem){
            try {
                fileSystem.close();
            }
            catch (IOException ex){
                System.out.println("----------Could not close the FileSystem----------");
            }
        }
        

        在执行代码之前,您应该在系统上运行 Hadoop。

        您只需要转到 HADOOP_HOME 并运行以下命令:

        ./sbin/start-all.sh

        完整参考请使用https://github.com/ksimar/HDFS_AppendAPI

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-02-11
          • 2021-11-25
          • 1970-01-01
          • 2015-11-25
          • 2017-10-25
          • 1970-01-01
          • 2014-07-04
          相关资源
          最近更新 更多