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属性。

相关文章
相关标签/搜索