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

Ven*_*k K 14 java hadoop mapreduce hdfs

在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);
Run Code Online (Sandbox Code Playgroud)

我从bufferedReader读取内容,一旦完成所有读取,我就关闭它.

这是读取它的代码段

String line;
while ((line = reader.readLine()) != null) {
    // Do something
}
Run Code Online (Sandbox Code Playgroud)

这段关闭读者的代码.

    if (bufferedReader != null) {
        bufferedReader.close();
    }
Run Code Online (Sandbox Code Playgroud)

这是我执行时发生的异常的堆栈跟踪bufferedReader.close().

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

我,[2013-11-18T04:56:51.601168#25683]信息 - :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] INFO - :attempt_201310111840_142285_r_000009_0:at sun.nio.cs.StreamDecoder.implClose(StreamDecoder.java:358)

I,[2013-11-18T04:56:51.601263#25683] INFO - :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] INFO - :attempt_201310111840_142285_r_000009_0:at java.io.BufferedReader.close(BufferedReader.java:497)

我不确定为什么会发生这种异常.这不是多线程的,因此,我不认为会出现任何形式的竞争条件.你能帮我理解吗

谢谢,

Venk

Joe*_*e K 35

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

因此,如果您尝试关闭BufferedReader,并尝试清除它已缓冲的某些数据,但基础流连接到已关闭的FileSystem,您将收到此错误.检查代码中是否有关闭FileSystem对象的其他位置,并查找竞争条件.另外,我相信Hadoop本身会在某个时候关闭FileSystem,所以为了安全起见,你应该只能从Reducer的setup,reduce或cleanup方法中访问它(或者配置,减少和关闭,具体取决于哪个API)你正在使用).


Mar*_*ier 18

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