【发布时间】:2013-12-10 09:19:07
【问题描述】:
我有两个进程正在运行。一个是将文件写入 HDFS,另一个是加载这些文件。
第一个进程(写入文件的进程)正在使用:
private void writeFileToHdfs(byte[] sourceStream, Path outFilePath) {
FSDataOutputStream out = null;
try {
// create the file
out = getFileSystem().create(outFilePath);
out.write(sourceStream);
} catch (Exception e) {
LOG.error("Error while trying to write a file to hdfs", e);
} finally {
try {
if (null != out)
out.close();
} catch (IOException e) {
LOG.error("Could not close output stream to hdfs", e);
}
}
}
第二个进程读取这些文件以进行进一步处理。 创建文件时,首先创建它,然后填充内容。此过程需要时间(几毫秒,但仍然如此),在此期间,第二个过程可能会在文件完全写入和关闭之前拾取文件。
请注意,HDFS 不会在名称节点中保留锁定信息 - 因此没有守护程序可以在访问文件之前检查文件是否已锁定。
我想知道解决此问题的最佳方法是什么。
以下是我的想法:
- 将文件完全写入并关闭后复制到新文件夹,然后进行第二个过程 将从这个新文件夹中读取。
- 根据某些命名约定重命名文件,一旦完全写入并关闭,然后是第二个进程 将根据此命名约定读取。
我有一种感觉,我正在尝试解决一个众所周知的问题,但我错过了一些东西。有解决此类问题的最佳做法吗?
【问题讨论】:
-
旁注:如果您使用的是 Java 7,则不需要做所有最后的事情,只需尝试使用资源
-
为什么不使用套接字在进程之间进行通信? P1 可以与 P2 通信,同时转储文件,这样如果它们不同时在线,P2 仍然可以稍后再接......
-
@RossDrew 我正在使用 java7,但对它很陌生。我去看看,谢谢。
-
@UmNyobe 我不确定我会得到你。我宁愿将流程解耦。