前言

在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. php+nginx上传文件配置

  2. LeetCode_Compare Version Numbers

    题目: Compare two version numbers version1 and version2. If version1 > version2 return 1, if versio ...

  3. Appium+python移动端自动化测试-环境搭建(一)

    搭建所在系统环境:Windows7版本64位系统 一.环境准备 jdk8.0.151 android-sdk_r20.3.4-windows python3.5 appium1.4.16.1 Node ...

  4. 3D游戏引擎中常见的三维场景管理方法

    对于一个有很多物体的3D场景来说,渲染这个场景最简单的方式就是用一个List将这些物体进行存储,并送入GPU进行渲染.当然,这种做法在效率上来说是相当低下的,因为真正需要渲染的物体应该是视椎体内的物体 ...

  5. 项目中遇到的问题, ftp等

    1:ftp 上传文件时的权限问题,需要将上传主目录下的文件权限设置为,这样用户就具有上传,操作,删除等权限 chmod  777 2:  当访问ftp时,出现以下提示.说明需要用户名和密码,这是在ft ...

  6. Linux环境下Netstat与PS的使用

    Linux下用netstat查看网络状态.端口状态 在linux一般使用netstat 来查看系统端口使用情况步. netstat命令是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表.实际 ...

  7. Yarn架构

    jobtracker存在单点故障问题 jobtracker只支持mapreduce,计算框架不具有可扩展性 jobtracker是性能瓶颈 yarn可以整合不同的计算框架,提高资源利用率 yarn的基 ...

  8. Mediakit报告设备商的空间不足以执行此操作的纯MAC解法

    使用Mac对磁盘进行分区,显示“Mediakit报告设备商的空间不足以执行此操作”,该怎么办? What 买了一个4TB的移动硬盘,准备进行分区给Time Machine用. 硬盘自带是HDFS的,所 ...

  9. Android 按钮 弹出对话框

    ackage com.example.helloworld; import android.os.Bundle;import android.app.Activity;import android.a ...

  10. Linux系统——Raid磁盘阵列

    Raid磁盘阵列 作用:解决磁盘速度.安全问题 Raid原理 Raid0 写入速度极快,有几块硬盘,写入速度就近似几倍,但是安全性极差,只要一块盘坏了,所有盘的数据全部坏掉,最少两块硬盘组合 性价比最 ...