java-使用Hadoop在datanode上写入临时文件的麻烦

我想在程序期间创建一个文件.但是,我不希望将此文件写在HDFS上,而是写在执行映射操作的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;
    }
}

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

有什么想法可以找到文件或错误消息吗?如果确实存在错误消息,我应该如何继续将文件写入datanode的本地文件系统?

解决方法:

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之间出现竞争状态.从旧的容器执行中遗留下来的文件还存在使本地磁盘空间混乱的风险.

日志消息将转到映射任务日志的stdout / stderr,但我怀疑执行未达到这些日志消息.相反,我怀疑您已经成功创建了文件,但是它要么不容易找到(目录结构中会有一些不可预知的事情,例如由YARN管理的应用程序ID和容器ID),或者在获得文件之前先对其进行清理对此.

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

上一篇:Hadoop2-8-0的环境搭建


下一篇:好程序员大数据教程分享之Hadoop优缺点