前言

在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/

hdfs的FileSystem实例化的更多相关文章

  1. FileSystem实例化过程

    HDFS案例代码 Configuration configuration = new Configuration(); FileSystem fileSystem = FileSystem.get(n ...

  2. 4、记录1----获取hdfs上FileSystem的方法 记录2:正则匹配路径:linux、hdfs

    /** * 获取hadoop相关配置信息 * @param hadoopConfPath 目前用户需要提供hadoop的配置文件路径 * @return */ public static Config ...

  3. HDFS之FileSystem

    package cn.hx.test; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.*; impo ...

  4. kafka-connect-hdfs连接hadoop hdfs时候,竟然是单点的,太可怕了。。。果断改成HA

    2017-08-16 11:57:28,237 WARN [org.apache.hadoop.hdfs.LeaseRenewer][458] - <Failed to renew lease ...

  5. Hadoop(五):HDFS的JAVA API基本操作

    HDFS的JAVA API操作 HDFS在生产应用中主要是客户端的开发,其核心步骤是从HDFS提供的api中构造一个HDFS的访问客户端对象,然后通过该客户端对象操作(增删改查)HDFS上的文件. 主 ...

  6. HDFS中Java的API使用测试

    import java.io.IOException; import java.util.Arrays; import java.util.Date; import java.util.Scanner ...

  7. Hadoop HDFS编程 API入门系列之从本地上传文件到HDFS(一)

    不多说,直接上代码. 代码 package zhouls.bigdata.myWholeHadoop.HDFS.hdfs5; import java.io.IOException; import ja ...

  8. HDFS文件系统基本文件命令、编程读写HDFS

    基本文件命令: 格式为:hadoop fs -cmd <args> cmd的命名通常与unix对应的命令名相同.例如,文件列表命令: hadoop fs -ls 1.添加目录和文件 HDF ...

  9. HDFS操作--文件上传/创建/删除/查询文件信息

    1.上传本地文件到HDFS //上传本地文件到HDFS public class CopyFile { public static void main(String[] args) { try { C ...

随机推荐

  1. android sdk 中跨平台部分

    跨平台部分: platforms samples sources system-images 这几个可以直接拷贝即可

  2. iass,pass,cass,sass,vm,container

    分布式存储hdfs 大文件,swift 对象存贮. 为七牛的CDN系统目前大部分还不是自建的,采用的是整合其它CDN的方式做的.也就是说出了七牛的文件分发使用的是网宿和蓝汛的老牌CDN的分发节点,自身 ...

  3. TestLink安装手册

    环境准备 系统CentOS Linux release 7.3.1611 (Core) 搭建LAMP所需的集成包 xampp-linux-x64-7.2.0-0-installer.run 下载地址 ...

  4. PDO 指南

    简介 前面咱已经见过MySQLi了,现在咱一起来看看PDO类.PDO是PHP Data Objects的缩写,它被描述为“在PHP中访问数据库的轻量级,兼容性的接口”.尽管它的名字不咋好听,但PDO是 ...

  5. Python并行编程(三):线程同步之Lock

    1.基础概念 当两个或以上对共享内存操作的并发线程中,如果有一个改变数据,又没有同步机制的条件下,就会产生竞争条件,可能会导致执行无效代码.bug等异常行为. 竞争条件最简单的解决方法是使用锁.锁的操 ...

  6. Pycharm配置同步服务器

    一.使用场景 我们一般需要将代码放到服务器上运行,但如果等我们将项目全部开发好之后再上传到服务器,而且每次在开发阶段需要经过多次修改,每修改一次,都手动上传一次,这样就太麻烦了,有没有一种方法可以达到 ...

  7. 007-aven-assembly-plugin和maven-jar-plugin打包,java启动命令

    一.需求 打一个zip包,包含如下: bin为程序脚本,启动和停止 lib为依赖包 根目录下为配置文件和项目jar包 二.知识储备 2.1.插件了解 plugin function maven-jar ...

  8. BlueZ

    一.BlueZ在ubuntu PC上的基础应用 1.bluez的安装及基本功能 dong@ubuntu:~/bluez$ lsbluez-5.47.tar.xz   SPP-loopback.pydo ...

  9. SpringMVC的映射器,适配器,控制器

    一.各司其职   (1)HandlerMapping映射器 根据客户端请求的url,找到处理本次请求的处理器,即将请求的路径和controller关联起来 (2)HandlerAdapter适配器 对 ...

  10. 开启mysql的远程访问

    1.登陆mysql数据库 mysql -u root -p 查看user表 mysql> use mysql;Database changedmysql> select host,user ...