FileSystem get(URI uri, Configuration conf) throws IOException{ Key key = new Key(uri, conf); return getInternal(uri, conf, key); }private FileSystem getInternal(URI uri, Configuration conf, Key key) throws IOException{ FileSystem fs; synchronized (this) { fs = map.get(key); } if (fs != null) { return fs; } fs = createFileSystem(uri, conf); synchronized (this) { // refetch the lock again FileSystem oldfs = map.get(key); if (oldfs != null) { // a file system is created while lock is releasing fs.close(); // close the new file system return oldfs; // return the old file system }// now insert the new file system into the map if (map.isEmpty() && !ShutdownHookManager.get().isShutdownInProgress()) { ShutdownHookManager.get().addShutdownHook(clientFinalizer, SHUTDOWN_HOOK_PRIORITY); } fs.key = key; map.put(key, fs); if (conf.getBoolean("fs.automatic.close", true)) { toAutoClose.add(key); } return fs; } }从这段代码中可以看出:
- 在Cache类内部维护了一个Map,该Map用于缓存已经连接好的FileSystem对象,Map的Kep为Cache.Key对象 。每次都会通过Cache.Key获取FileSystem,如果未获取到,才会继续创建的流程 。
- 在Cache类内部维护了一个Set(toAutoClose),该Set用于存放需自动关闭的连接 。在客户端关闭时会自动关闭该集合中的连接 。
【线上内存泄漏引发OOM问题分析和解决】 /** FileSystem cache */ static final Cache CACHE = new Cache();也就是说,该CACHE对象会一直存在不会被回收 。而每次创建的FileSystem都会以Cache.Key为key,FileSystem为Value存储在Cache类中的Map中 。那至于在缓存时候是否对于相同hdfs URI是否会存在多次缓存,就需要查看一下Cache.Key的hashCode方法了,如下:
@Override public int hashCode() { return (scheme + authority).hashCode() + ugi.hashCode() + (int)unique; }可见,schema和authority变量为String类型,如果在相同的URI情况下,其hashCode是一致 。unique在FilSystem.getApi下也不用关心,因为每次该参数的值都是0 。那么此处需要重点关注一下ugi.hashCode() 。
至此,来小结一下:
- 在获取FileSystem时,FileSystem内置了一个static的Cache,该Cache内部有一个Map,用于缓存已经获取的FileSystem连接 。
- 参数fs.hdfs.impl.disable.cache,用于控制FileSystem是否需要缓存,默认情况下是false,即缓存 。
- Cache中的Map,Key为Cache.Key类,该类通过schem,authority,UserGroupInformation,unique 4个参数来确定一个Key,如上Cache.Key的hashCode方法 。
推荐阅读
- 社保卡丢了坏了 线上线下都能补!
- 使用google-perftools优化nginx内存管理提升性能
- 物理内存与虚拟内存
- iOS和Android OS的内存管理机制,这才是流畅的根本原因
- 电脑开机不显示?都是内存惹的祸,教你处理此类故障
- 家庭网络配置问题案例:六类网线上网速度只有100兆
- 手机用什么牌子的内存卡最好 手机内存卡十大名牌
- 如何在 Linux 中找出内存消耗最大的进程
- 微软|微软Edge 100版浏览器神级优化:CPU占用降低99%、内存降低85%
- 为什么买内存条要看时序?它有啥作用