在reduce设置方法中,我尝试关闭 BufferedReader
对象和获取 FileSystem
关闭异常。这种情况并非总是发生。这是我用来创建 BufferedReader
.
String fileName = <some HDFS file path>
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
Path hdfsPath = new Path(filename);
FSDataInputStream in = fs.open(hdfsPath);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
我从bufferedreader读取内容,一旦所有的读取完成,我就关闭它。
这是一段读取它的代码
String line;
while ((line = reader.readLine()) != null) {
// Do something
}
这是关闭读卡器的一段代码。
if (bufferedReader != null) {
bufferedReader.close();
}
这是在执行 bufferedReader.close()
.
i、 [2013-11-18t04:56:51.601135#25683]信息--:尝试\u 201310111840 \u 142285 \u r\u000009 \u 0:org.apache.hadoop.hdfs.dfsclient.checkopen(dfsclient)。java:565)
i、 [2013-11-18t04:56:51.601168\25683]信息--:尝试\u 201310111840\u 142285\u r\u000009\u 0:org.apache.hadoop.hdfs.dfsinputstream.close(dfsinputstream)。java:522)
i、 [2013-11-18t04:56:51.601199#25683]信息--:尝试\u 201310111840 \u 142285 \u r\u000009 \u 0:at java.io.filternputstream.close(filternputstream)。java:155)
i、 [2013-11-18t04:56:51.601230#25683]信息--:尝试\u 201310111840 \u 142285 \u r\u000009 \u 0:at sun.nio.cs.streamdecoder.implclose(streamdecoder)。java:358)
i、 [2013-11-18t04:56:51.601263]信息--:尝试\u 201310111840 \u 142285 \u r\u000009 \u 0:at sun.nio.cs.streamdecoder.close(streamdecoder)。java:173)
i、 [2013-11-18t04:56:51.601356#25683]信息--:尝试\u 201310111840 \u 142285 \u r\u000009 \u 0:at java.io.inputstreamreader.close(inputstreamreader)。java:182)
i、 [2013-11-18t04:56:51.601395#25683]信息--:尝试\u 201310111840 \u 142285 \u r\u000009 \u 0:at java.io.bufferedreader.close(bufferedreader。java:497)
我不知道为什么会发生这种例外。这不是多线程的,因此,我不希望有任何形式的竞争条件。你能帮我理解吗。
谢谢,
杨子朴
2条答案
按热度按时间qij5mzcb1#
hadoop文件系统api有一个鲜为人知的问题:
FileSystem.get
对于具有相同文件系统的每次调用,返回相同的对象。所以,如果一个地方关闭了,它们都关闭了。你可以辩论这个决定的优点,但事实就是这样。因此,如果您试图关闭bufferedreader,它试图清除它缓冲的一些数据,但是底层流连接到一个已经关闭的文件系统,您将得到这个错误。在关闭文件系统对象的任何其他地方检查代码,并查找争用条件。另外,我相信hadoop本身会在某个时候关闭文件系统,所以为了安全起见,您可能只能从reducer的setup、reduce或cleanup方法中访问它(或者配置、reduce和close,具体取决于您使用的api)。
2hh7jdfx2#
你必须使用
FileSystem.newInstance
避免使用共享连接(如joek所述)。它将为您提供一个唯一的、非共享的示例。