web-dev-qa-db-ja.com

BufferedReader.close()を実行すると、HadoopFileSystemが例外を閉じました

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()を実行したときに発生する例外のスタックトレースです。

私、[2013-11-18T04:56:51.601135#25683]情報-:attempt_201310111840_142285_r_000009_0:org.Apache.hadoop.hdfs.DFSClient.checkOpen(DFSClient.Java:565)

私、[2013-11-18T04:56:51.601168#25683]情報-:attempt_201310111840_142285_r_000009_0:org.Apache.hadoop.hdfs.DFSInputStream.close(DFSInputStream.Java:522)

I、[2013-11-18T04:56:51.601199#25683]情報-:attempt_201310111840_142285_r_000009_0:Java.io.FilterInputStream.close(FilterInputStream.Java:155)

私、[2013-11-18T04:56:51.601230#25683]情報-:attempt_201310111840_142285_r_000009_0:Sun.nio.cs.StreamDecoder.implClose(StreamDecoder.Java:358)

私、[2013-11-18T04:56:51.601263#25683]情報-:attempt_201310111840_142285_r_000009_0:Sun.nio.cs.StreamDecoder.close(StreamDecoder.Java:173)

私、[2013-11-18T04:56:51.601356#25683]情報-:attempt_201310111840_142285_r_000009_0:Java.io.InputStreamReader.close(InputStreamReader.Java:182)

私、[2013-11-18T04:56:51.601395#25683]情報-:attempt_201310111840_142285_r_000009_0:Java.io.BufferedReader.close(BufferedReader.Java:497)

この例外が発生している理由がわかりません。これはマルチスレッドではないので、いかなる種類の競合状態も発生するとは思われません。私が理解するのを手伝ってくれませんか。

ありがとう、

ヴェンク

14
Venk K

HadoopファイルシステムAPIにはあまり知られていない落とし穴があります:FileSystem.getは、同じファイルシステムでのすべての呼び出しに対して同じオブジェクトを返します。したがって、1つがどこかで閉じられている場合、それらはすべて閉じられます。この決定のメリットについて議論することもできますが、それはその通りです。

したがって、BufferedReaderを閉じようとして、バッファリングされたデータをフラッシュしようとしたが、基になるストリームがすでに閉じられているファイルシステムに接続されている場合、このエラーが発生します。 FileSystemオブジェクトを閉じる他の場所がないかコードを確認し、競合状態を探します。また、Hadoop自体はある時点でファイルシステムを閉じると思います。安全のために、おそらく、Reducerのセットアップ、リデュース、またはクリーンアップメソッド(または構成、リデュース、クローズ)内からのみアクセスする必要があります。使用しています)。

35
Joe K

共有接続の使用を回避するには、FileSystem.newInstanceを使用する必要があります(Joe Kによる説明)。一意の非共有インスタンスが提供されます。

18
Marius Soutier