我想在我的程序中创建一个文件。但是,我不希望这个文件写在hdfs上,而是写在datanode文件系统上 map
执行操作。
我尝试了以下方法:
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条答案
按热度按时间sz81bmfz1#
newfile.txt是一个相对路径,因此该文件将相对于Map任务进程的工作目录显示。这将落在nodemanager用于容器的目录下的某个地方。这是配置属性
yarn.nodemanager.local-dirs
在yarn-site.xml中,或从/tmp下的yarn-default.xml继承的默认值:下面是我的测试环境中一个这样的目录的具体示例:
这些目录是容器执行的临时空间,因此它们不是持久性所依赖的。后台线程会定期删除这些已完成容器的文件。可以通过设置配置属性来延迟清理
yarn.nodemanager.delete.debug-delay-sec
在yarn-site.xml中:但是,请记住,此配置仅用于解决问题,以便您可以更轻松地查看目录。不建议将其作为永久性生产配置。如果应用程序逻辑依赖于删除延迟,那么很可能会导致尝试访问目录的应用程序逻辑与尝试删除目录的节点管理器之间出现争用情况。保留旧容器执行时留下的文件也有可能造成本地磁盘空间混乱。
日志消息将转到map任务日志的stdout/stderr,但我怀疑执行没有命中这些日志消息。相反,我怀疑您成功地创建了该文件,但它不是很容易找到的(目录结构将有一些不可预知的东西,如由yarn管理的应用程序id和容器id),就是在您可以访问它之前,该文件正在被清理。
如果您将代码更改为使用指向其他目录的绝对路径,那么这会有所帮助。然而,我并不期望这种方法在实际操作中能很好地工作。由于hadoop是分布式的,您可能很难在成百上千的集群中找到哪个节点包含您想要的本地文件。相反,最好先写入hdfs,然后将本地需要的文件拉到启动作业的节点。