使用HDFS FileSystem实例时应该注意的问题

概述

对于通过编程,使用API来对HDFS进行操作的场景,其中一个需要考虑的问题是如何管理FileSystem实例(确切地说是DistributedFileSystem实例),通过查询文档,发现它是线程安全的

但是这里的“线程安全”是指客户端的操作(创建文件夹、删除文件夹、创建文件...),但是FileSystem实例本身在不同线程间共享,却不是“安全”的。如果有两个线程使用同一个FileSystem实例进行操作,那么在线程任务中一定不能调用FileSystem实例的close方法,因为关闭之后,另一个线程使用这个实例的时候,就会报错:

事实上,从HDFS的实现来看,它鼓励这样一种使用模式所有的线程共享同一个FileSystem实例,但是一定不要手动调用此实例的close方法,否则它就有可能变得不再安全。HDFS的实现中,FileSystem.get(Configuration conf)会从缓存中获取FileSystem实例,每个线程中获取的都是同一个实例。

如果出于某种原因,在不同的线程中使用全新的FileSystem实例,那么需要同时满足两个条件:

1. 设置fs.hdfs.impl.disable.cache为true;

2. 使用方法FileSystem.get(uri, conf)来获取实例,同时要满足:

  1. uri的scheme和authority信息必须提供;
  2. scheme必须和fs.defaultFS URI的scheme相同;

为了在不同线程中使用全新的FileSystem实例,要求同时满足这些条件,这从另一个侧面是说,HDFS的实现实际上是鼓励共享FileSystem实例的。为什么要这样做?

如果设置了fs.hdfs.impl.disable.cache,每个线程使用符合条件的URI(和fs.defaultFS scheme相同),那就会创建一个崭新的FileSystem实例,如果忘记close,就会造成内存泄露;比如要删除HDFS上 100万个文件,每次都用文件的URI来获取FileSystem实例,并且忘记删除完文件后调用FileSystem实例的close方法,那么就会造成有100万个FileSystem实例在内存中,发生了内存泄露;

这样设计好不好?

从持有Explicit is better than implicit观点的人来看,这显然不够明确,他们认为文件系统对象使用之后显然应该手动去关闭,但是一碰到这种设计,手动关闭反而产生了潜在的风险;从另一个方面这种设计防止了大量创建FileSystem对象,从而防止创建大量的DFSClient,以防止大量对NameNode的连接。从其发挥的作用来看,这种设计又是必要的。综合来看这种设计是合理的,至于有没有更好的设计方案,还需要进一步思考。

以上。

 

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值