使用Hadoop在datanode上编写临时文件的麻烦

时间:2014-08-07 14:07:25

标签: java hadoop hdfs yarn hadoop2

我想在程序中创建一个文件。但是,我不希望这个文件写在HDFS上,而是写在执行map操作的datanode文件系统上。

我尝试了以下方法:

public void map(Object key, Text value, Context context)
        throws IOException, InterruptedException {
    // do some hadoop stuff, like counting words
    String path = "newFile.txt";
    try {
        File f = new File(path);
        f.createNewFile();
    } catch (IOException e) {
        System.out.println("Message easy to look up in the logs.");
        System.err.println("Error easy to look up in the logs.");
        e.printStackTrace();
        throw e;
    }
}

使用绝对路径,我得到它应该是的文件。使用相对路径,这个代码不会产生任何错误,无论是在我运行程序的控制台中还是在作业日志中。但是,我无法找到应该创建的文件(现在,我正在使用本地群集)。

任何想法在哪里找到文件或错误消息?如果确实有错误消息,我该如何继续将文件写入datanodes的本地文件系统?

1 个答案:

答案 0 :(得分:3)

newFile.txt是一个相对路径,因此该文件将显示相对于您的地图任务进程的工作目录。这将落在NodeManager用于容器的目录下。这是yarn-site.xml中的配置属性yarn.nodemanager.local-dirs,或者是来自yarn-default.xml的默认值,它位于/ tmp:

<property>
  <description>List of directories to store localized files in. An 
    application's localized file directory will be found in:
    ${yarn.nodemanager.local-dirs}/usercache/${user}/appcache/application_${appid}.
    Individual containers' work directories, called container_${contid}, will
    be subdirectories of this.
  </description>
  <name>yarn.nodemanager.local-dirs</name>
  <value>${hadoop.tmp.dir}/nm-local-dir</value>
</property>

以下是我的测试环境中一个此类目录的具体示例:

/tmp/hadoop-cnauroth/nm-local-dir/usercache/cnauroth/appcache/application_1363932793646_0002/container_1363932793646_0002_01_000001

这些目录是容器执行的临时空间,因此它们不是您可以依赖的持久性的东西。后台线程会定期删除已完成容器的这些文件。可以通过在yarn-site.xml中设置配置属性yarn.nodemanager.delete.debug-delay-sec来延迟清理:

<property>
  <description>
    Number of seconds after an application finishes before the nodemanager's 
    DeletionService will delete the application's localized file directory
    and log directory.

    To diagnose Yarn application problems, set this property's value large
    enough (for example, to 600 = 10 minutes) to permit examination of these
    directories. After changing the property's value, you must restart the 
    nodemanager in order for it to have an effect.

    The roots of Yarn applications' work directories is configurable with
    the yarn.nodemanager.local-dirs property (see below), and the roots
    of the Yarn applications' log directories is configurable with the 
    yarn.nodemanager.log-dirs property (see also below).
  </description>
  <name>yarn.nodemanager.delete.debug-delay-sec</name>
  <value>0</value>
</property>

但是,请记住,此配置仅用于解决问题,以便您可以更轻松地查看目录。不建议将其作为永久性生产配置。如果应用程序逻辑依赖于删除延迟,那么这可能会导致尝试访问目录的应用程序逻辑与尝试删除目录的NodeManager之间出现争用情况。保留旧容器执行中遗留的文件也可能会使本地磁盘空间混乱。

日志消息将转到map任务日志的stdout / stderr,但我怀疑执行没有击中那些日志消息。相反,我怀疑你是成功创建文件,但要么它不容易找到(目录结构将有一些不可预测的东西,如应用程序ID和YARN管理的容器ID),或者文件正在清理之前你得到它。

如果您更改了代码以使用指向其他目录的绝对路径,那么这将有所帮助。但是,我不希望这种方法在实际操作中运作良好。由于Hadoop是分布式的,因此您可能很难找到数百或数千个集群中的哪个节点包含您想要的本地文件。相反,您可能最好写入HDFS,然后将本地需要的文件提取到启动作业的节点。