Hadoop文件系统在执行BufferedReader.close()时关闭异常



在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-18t4:56:51.601135#25683〕信息-:attempt_20130111840_142285_r_ 000009_0:在org.apache.hoop.hdfs.DFSClient.checkOpen(DFSClient.java)

I、 〔2013-11-18t4:56:51.601168#25683〕信息-:attempt_20130111840_142285_r_ 000009_0:在org.apache.hoop.hdfs.DFSInputStream.close(DFSInput Stream.java:522)

I、 〔2013-11-18t4:56:51.601199#25683〕信息-:attempt_20130111840_142285_r_ 000009_0:在java.io.FilterInputStream.close(FilterInputStream.java:155)

I、 〔2013-11-18t4:56:51.601230#25683〕信息-:attempt_20130111840_142285_r_ 000009_0:在sun.nio.cs.StreamDecoder.implClose(StreamDecoder.java:358)

I、 〔2013-11-18t4:56:51.601263#25683〕信息-:attempt_20130111840_142285_r_ 000009_0:在sun.nio.csStreamDecoder.close(StreamDecoder.java:173)

I、 〔2013-11-18t4:56:51.601356#25683〕信息-:attempt_20130111840_142285_r_ 000009_0:在java.io.InputStreamReader.close(InputStreamReader.java:182)

I、 〔2013-11-18t4:56:51.601395#25683〕信息-:attempt_20130111840_142285_r_ 000009_0:在java.io.BufferedReader.close(BufferedReader.java:497)

我不知道为什么会发生这种异常情况。这不是多线程的,所以我不希望有任何形式的竞争条件。你能帮我理解吗。

谢谢,

Venk

hadoop文件系统API有一个鲜为人知的问题:FileSystem.get对同一文件系统的每次调用都返回相同的对象。因此,如果一个在任何地方都关闭了,那么它们都是关闭的。你可以争论这个决定的优点,但事实就是这样

因此,如果您试图关闭BufferedReader,并且它试图清空它缓冲的一些数据,但底层流连接到一个已经关闭的文件系统,则会出现此错误。检查您的代码中关闭FileSystem对象的任何其他位置,并查找竞争条件。此外,我相信Hadoop本身会在某个时候关闭FileSystem,因此为了安全起见,您可能只应该从Reducer的设置、减少或清理方法中访问它(或者配置、减少和关闭,取决于您使用的API)。

您必须使用FileSystem.newInstance来避免使用共享连接(如Joe K所述)。它将为您提供一个唯一的、非共享的实例。

相关内容

  • 没有找到相关文章

最新更新