Hadoop FileSystem 在执行 BufferedReader.close() 时关闭了异常

2022-09-03 16:28:34

在 Reduce setup 方法中,我正在尝试关闭一个对象并得到一个关闭的异常。它不会一直发生。这是我用来创建 .BufferedReaderFileSystemBufferedReader

    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);

我从缓冲阅读器读取内容,一旦所有读取完成,我就关闭它。

这是读取它的代码段

String line;
while ((line = reader.readLine()) != null) {
    // Do something
}

这是关闭读取器的代码段。

    if (bufferedReader != null) {
        bufferedReader.close();
    }

这是我执行 .bufferedReader.close()

I, [2013-11-18T04:56:51.601135 #25683] INFO -- : attempt_201310111840_142285_r_000009_0: at org.apache.hadoop.hdfs.DFSClient.checkOpen(DFSClient.java:565)

I, [2013-11-18T04:56:51.601168 #25683] INFO -- : attempt_201310111840_142285_r_000009_0: at org.apache.hadoop.hdfs.DFSInputStream.close(DFSInputStream.java:522)

I, [2013-11-18T04:56:51.601199 #25683] INFO -- : attempt_201310111840_142285_r_000009_0: at java.io.FilterInputStream.close(FilterInputStream.java:155)

I, [2013-11-18T04:56:51.601230 #25683] 信息 -- : attempt_201310111840_142285_r_000009_0: at sun.nio.cs.StreamDecoder.implClose(StreamDecoder.java:358)

I, [2013-11-18T04:56:51.601263 #25683] 信息 -- : attempt_201310111840_142285_r_000009_0: at sun.nio.cs.StreamDecoder.close(StreamDecoder.java:173)

I, [2013-11-18T04:56:51.601356 #25683] INFO -- : attempt_201310111840_142285_r_000009_0: at java.io.InputStreamReader.close(InputStreamReader.java:182)

I, [2013-11-18T04:56:51.601395 #25683] 信息 -- : attempt_201310111840_142285_r_000009_0: at java.io.BufferedReader.close(BufferedReader.java:497)

我不确定为什么会发生这种异常。这不是多线程的,因此,我不希望存在任何形式的竞争条件。你能帮我理解吗?

谢谢

文克


答案 1

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

因此,如果您尝试关闭 BufferedReader,并且它尝试清除已缓冲的一些数据,但基础流已连接到已关闭的文件系统,则会出现此错误。检查代码中是否有其他位置要关闭文件系统对象,并查找争用条件。另外,我相信Hadoop本身会在某个时候关闭文件系统,所以为了安全起见,你可能应该只从 Reducer 的设置、reduce 或清理方法(或者配置、reduce 和关闭,具体取决于你使用的 API)中访问它。


答案 2

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


推荐