zoukankan      html  css  js  c++  java
  • hdfs的FileSystem实例化

    前言

    在spark中通过hdfs的java接口并发写文件出现了数据丢失的问题,一顿操作后发现原来是FileSystem的缓存机制。补一课先

    FileSystem实例化

    FileSystem.get(config)是如何创建一个hadoop的FileSystem。
    分为3个步骤。
    1.  初始化所有支持的FileSystem(没有实例话,只是缓存类)
    2.  通过uri的scheme拿到相应FileSystem
    3.  缓存机制(如果不关闭的话,默认是开启)
     
    下面详细分析一下各步骤流程
    1.   初始化
    通过java提供的ServiceLoader来录入所有可能的FileSystem,就像这样
    ServiceLoader<FileSystem> serviceLoader = ServiceLoader.load(FileSystem.class);
    for (FileSystem fs : serviceLoader) {
      SERVICE_FILE_SYSTEMS.put(fs.getScheme(), fs.getClass());
    }
    待初始化的类通过配置文件声明,配置可以在hadoop-hdfs.jar里找到

    捎带一嘴,java提供的ServiceLoader有点像乞丐版spring的依赖反转。

    2.scheme
    通过对Uri的解析来判断创建一个什么FileSystem,
    例如
    hdfs://master:9200/test的scheme就是hdfs。

    然后通过scheme和已经缓存好的FileSystem映射,找到需要实例化的类。

    例如scheme是hdfs,那么就会创建一个DistributedFileSystem。

    3. 缓存

    FileSystem类中有一个Cache内部类,用于缓存已经被实例化的FileSystem。注意这个跟连接池还是有区别的,Cache中的缓存只是一个map,可以被多个线程拿到。这就会有一个问题,当你多线程同时get FileSystem的时候,可能返回的是同一个对象。所以切记,在多线程场景中,不要随意调用FileSystem.close,你关的连接可能会影响到其他正在使用的线程。

    注意: 当你在其他框架上拿fileSystem对象需要额外注意,例如在spark上进行 FileSystem.get(),如果你想自定义某些配置,设置hdfs的副本数(dfs.replication) 之类,你必须在configuration中关闭FileSystem的缓存机制,也就是设置

    configuration.set("fs.hdfs.impl.disable.cache","true")

    这很重要,因为你不确定spark是否在你之前创建了一个FileSystem,而你得到的可能不是你想要的。

    参考资料

    // 遇到的相同问题

    https://www.darkal.cn/2017/03/filesystem-get%E4%BB%8E%E7%BC%93%E5%AD%98cache%E4%B8%AD%E8%8E%B7%E5%BE%97%E8%BF%9E%E6%8E%A5%E5%AF%BC%E8%87%B4%E7%9A%84%E9%97%AE%E9%A2%98/

  • 相关阅读:
    按钮-全选复选框 PENGHAO
    ASP.NET技术内幕的电子书中文版 PENGHAO
    hotmail和gmail 邮件中背景图片无效不显示的解决办法
    Silverlight之DataGrid的列格式化日期
    MS SQL基础
    JS获得当前地址栏url
    Javascript实现复制到剪贴板
    C#.NET画验证码与Cookie验证
    网站部署与定制
    操作SQL数据库常用语句
  • 原文地址:https://www.cnblogs.com/ulysses-you/p/7930903.html
Copyright © 2011-2022 走看看