FileSystem.get從緩存cache中得到鏈接致使的問題

首先了解FileSyste.get機制,查看源碼可知,首先會根據fs.hdfs.impl.disable.cache,是否去緩存cache中找鏈接,默認是去緩存中找鏈接的,參考:HDFS下載數據之源碼分析-FileSystem.get(conf)_block01html

因此就存在複用FileSystem的狀況,當複用FileSystem時,若是多線程都有關閉FileSystem,就會報錯,提示Filesystem closed,最後一行是DFSClient.checkOpen。這是由於這個方法會去判斷若是FileSystem已經關閉,就會拋出一個異常。java

 java.io.IOException: Filesystem closed
        at org.apache.hadoop.hdfs.DFSClient.checkOpen(DFSClient.java:795)

由上面所致使的狀況有多種,下面就是2種比較典型的node

1.當Spark和HDFS api同時存在時,當你的hdfs api去調用FileSystem的close方法時,會報上面的錯誤,由於他們都是去cache中獲取鏈接,而你的api close了fileSystem,致使spark的hdfs鏈接不能用。因此會報錯。web

參考:hadoop/spark關閉鉤子研究shell

2.hadoop運行mapreduce任務時,因爲多個datanode節點須要讀取hdfs filesystem,此時,若是一個節點由於網絡或者其餘緣由關掉了該filesystem,而其餘節點仍然使用的cache中的filesystem,致使觸發IOExceptionapache

出現這個問題是在hive使用的時候出現的api

參考:hive查詢hdfs數據時,遇到的兩個hadoop配置問題緩存

3.hive由fs.hdfs.impl.disable.cache參數引發的重寫分區數據的異常網絡

解決方案:fs.hdfs.impl.disable.cache使用默認值,也就是false。每種狀況下面再細細分析。多線程

分析狀況:

狀況1:這裏是spark和hdfs api共用致使的,並非hadoop的設計缺陷,只是你後去spark和hdfs api沒有協調好,沒有用好,因此建議在hdfs api中不close任何東西,等spark集羣去close。

狀況2:打開參考的那麼文章,有這麼一句,「若是一個節點由於網絡或者其餘緣由」,這是由於外部緣由,hadoop系統自己設計是沒有問,因此這裏應該讓hive或者mapreduce優化FileSystem的使用方式。

狀況3:若是將fs.hdfs.impl.disable.cache改變了,那麼狀況3的問題就會出現。由於官方的core-site.xml都沒有出現這個屬性,因此咱們不能輕易的去改變他。

因此最後選擇哪一種方法,只能本身去權衡了。建議不要修改fs.hdfs.impl.disable.cache屬性。

相關文章
相關標籤/搜索