hadoop应用开发技术..._不要调用Hadoop的FileSystem#close

好久没写博客了,今天来聊一聊踩到的一个Hadoop的坑。

Hadoop把对于文件系统的调用封装成了一个FileSystem类,使得新的文件系统的提供者只要实现这个接口就可以接入到Hadoop生态体系的各个计算引擎里面比如Spark, Presto等等,非常的方便。FileSystem类实现了Closable的接口:

public 

对于Java新特性使用的比较溜的同学在使用FileSystem的时候自然就会想用到try的语法以实现在使用完FileSystem自动关闭的效果:

try 

从纯Java语法的角度看起来完全没毛病,无比的正确。但是在FileSystem这个类的实现里面藏了一个坑: FileSystem对于文件系统类的实例做了缓存,如果是来自同一个文件系统,它会返回同一个实例:

public 

某种程度上相当于搞了个全局变量。那为什么要做这个cache呢,原因在于如果不做cache,每个FileSystem的实例都会建立一个到HDFS Namenode的连接(如果底层连接的是HDFS的话),而在大数据计算的场景下,MapReduce/Spark要对HDFS进行大量并发的读,不做缓存会造成超量的连接打到namenode上,造成DDOS的效果。

做了这个cache就意味着你从FileSystem里面拿到的文件系统的实例可能别人也拿到了,而且可能正在用,你如果用try语法,或者用完之后主动close掉,就会导致这个文件系统实例的其它使用方意外出错。

这个问题也是有解的,网络上比较常见的一类说法是disable掉FileSystem内部的cache, 但是如果底层用的确实是HDFS的话,显然是有性能问题的。

还有一个解法是不要去close我们拿到的FileSystem, 那么会不会有“泄漏“呢,FileSystem的设计者其实考虑到了这个问题,它有一个shutdown的hook会负责最后关掉这些FileSystem:

// now insert the new file system into the map

因为缓存的粒度是文件系统级别的,一般的应用文件系统的个数不应该太多,所以不会是个大问题。

但是这样整体的设计整体看来还是蛮坑的,不踩过一次估计很难知道,江湖一直传言Google的工程师们觉得Hadoop体系代码写的很渣,不知道这个点是不是其中之一。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值