hadoop文件系统体系

  在用Hadoop框架处理大数据时使用最多就是HDFS--分布式文件系统,但Hadoop的文件系统不仅只有分布式文件系统,例如:hfs,HSFTP,HAR等在Hadoop中都是有集成的,用来处理存储在不同体系中的数据。事实上应该这么说,Hadoop其实是一个综合性的文件系统。

  下面来看看文件系统的结构体系

  

当然上面的UML图解事实上有些冗余,但是为了能清楚的表达fs这个体系中的成员,我尽量把所有的成员罗列了进来。在Hadoop的文件系统体系中FileSystem是其他成员的父类,它是一个抽象类,旨在通过它来定义一个访问文件系统的标准,在Hadoop框架中的其他组件在使用到文件系统时只认识FileSystem类提供的标准,所以如果自己在定义一个文件系统是定要按照这个标准来(当然,说说而已,我也没尝试过),面对抽象编程在我看来就是按照某些标准来编程。至于在FileSystem的子类中,到底仅仅是实现了抽象的方法,还是同时也重写了父类的方法,我觉得不重要,最重要的是明白这种设计思想。

  在使用文件系统是一般的通过FileSystem.get(Configuration conf)或者是FileSystem.get(URI uri,Configuration conf)来获取文件系统的实例,这两种方法时高度一致的,我们来看看源码

public static FileSystem get(URI uri, Configuration conf) throws IOException {
  String scheme = uri.getScheme();
  String authority = uri.getAuthority();

  if (scheme == null) { // no scheme: use default FS
    return get(conf);
  }

  if (authority == null) { // no authority
  URI defaultUri = getDefaultUri(conf);
  if (scheme.equals(defaultUri.getScheme()) // if scheme matches default
    && defaultUri.getAuthority() != null) { // & default has authority
  return get(defaultUri, conf); // return default
  }

}

  String disableCacheName = String.format("fs.%s.impl.disable.cache", scheme);
    if (conf.getBoolean(disableCacheName, false)) {
      return createFileSystem(uri, conf);
  }

return CACHE.get(uri, conf);

}

  /** Returns the configured filesystem implementation.*/
  public static FileSystem get(Configuration conf) throws IOException {
    return get(getDefaultUri(conf), conf);
}

  public static URI getDefaultUri(Configuration conf) {
    return URI.create(fixName(conf.get(FS_DEFAULT_NAME_KEY, "file:///")));
  }

在调用FileSystem.get(Configuration conf)的时候,事实上还是调用了FileSystem.get(URI uri,Configuration conf),使用FileSystem.get(Configuration conf)来获取文件系统的实例时会去读取配置文件core-site.xml中键fs.default.name对应的value,如果不存在该项配置,默认使用的file:///也就是本地文件系统。使用FileSystem.get(conf)方法时,会去读取配置文件,这样在后期更换文件系统时就很方便了。当然使用FileSystem.get(uri,conf)时也可以很好的实现后期文件系统的修改,直接在程序运行时加入参数就行了。现在剩下的问题就落在FileSystem.get(uri,conf)的头上了,大权握在它的手上了。来看看通过这个方法是怎么得到具体的文件系统实例的,在验证uri的结构完整后,通过createFileSystem(uri, conf)来返回FileSystem的实例,在CACHE.get(uri, conf)方法的内部同样也会调用createFileSystem(uri, conf),那么问题就落在了这个方法上了,下面来看看createFileSystem(uri, conf)的源码,就明白了是怎么回事了

private static FileSystem createFileSystem(URI uri, Configuration conf
      ) throws IOException {
    Class<?> clazz = conf.getClass("fs." + uri.getScheme() + ".impl", null);
    LOG.debug("Creating filesystem for " + uri);
    if (clazz == null) {
      throw new IOException("No FileSystem for scheme: " + uri.getScheme());
    }
    FileSystem fs = (FileSystem)ReflectionUtils.newInstance(clazz, conf);
    fs.initialize(uri, conf);
    return fs;
  }

这下就明了了,Class<?> clazz = conf.getClass("fs." + uri.getScheme() + ".impl", null);通过读取core-default.xml中fs.[scheme].impl的value值来得到FileSystem实现类的字节码文件,有了Class文件其他的事情就好说了,此时相当于是把整个类的所有细节都暴露给programmer了,通过反射技术操作Class从而就得到了文件系统的实例。下面是core-default.xml中关于这部分的配置片段

<property>
  <name>fs.file.impl</name>
  <value>org.apache.hadoop.fs.LocalFileSystem</value>
  <description>The FileSystem for file: uris.</description>
</property>

<property>
  <name>fs.hdfs.impl</name>
  <value>org.apache.hadoop.hdfs.DistributedFileSystem</value>
  <description>The FileSystem for hdfs: uris.</description>
</property>

<property>
  <name>fs.s3.impl</name>
  <value>org.apache.hadoop.fs.s3.S3FileSystem</value>
  <description>The FileSystem for s3: uris.</description>
</property>

<property>
  <name>fs.s3n.impl</name>
  <value>org.apache.hadoop.fs.s3native.NativeS3FileSystem</value>
  <description>The FileSystem for s3n: (Native S3) uris.</description>
</property>

<property>
  <name>fs.kfs.impl</name>
  <value>org.apache.hadoop.fs.kfs.KosmosFileSystem</value>
  <description>The FileSystem for kfs: uris.</description>
</property>

<property>
  <name>fs.hftp.impl</name>
  <value>org.apache.hadoop.hdfs.HftpFileSystem</value>
</property>

<property>
  <name>fs.hsftp.impl</name>
  <value>org.apache.hadoop.hdfs.HsftpFileSystem</value>
</property>

<property>
  <name>fs.webhdfs.impl</name>
  <value>org.apache.hadoop.hdfs.web.WebHdfsFileSystem</value>
</property>

<property>
  <name>fs.ftp.impl</name>
  <value>org.apache.hadoop.fs.ftp.FTPFileSystem</value>
  <description>The FileSystem for ftp: uris.</description>
</property>

<property>
  <name>fs.ramfs.impl</name>
  <value>org.apache.hadoop.fs.InMemoryFileSystem</value>
  <description>The FileSystem for ramfs: uris.</description>
</property>

<property>
  <name>fs.har.impl</name>
  <value>org.apache.hadoop.fs.HarFileSystem</value>
  <description>The filesystem for Hadoop archives. </description>
</property>

  在上面的文件系统体系图中有三处被标记的类,下面通过这三个类来说说文件系统能否支持验证检验和的设置。什么是检验和?检验和是在文件写入或者是读取阶段用来验证数据大小是否存在差池的数据统计信息(姑且这么说),检验和的作用主要是保证数据的完整性。在hadoop中保证数据的完整性就是通过读写时对检验和的验证来实现。在hadoop的FS中,不是所有的底层文件系统都支持验证检验和的。通过LocalFileSystem和RawLocalFileSystem来说明什么样的底层文件系统支持验证检验和。

  LocalFileSystem是一个支持验证检验和的文件系统

public LocalFileSystem() {
    this(new RawLocalFileSystem());
  }

  public FileSystem getRaw() {
    return rfs;
  }

  public LocalFileSystem(FileSystem rawLocalFileSystem) {
    super(rawLocalFileSystem);
    rfs = rawLocalFileSystem;
  }

上面是LocalFileSystem的构造函数,从构造函数可以看出,LocalFileSystem底层使用就是RawLocalFileSystem(不支持验证检验和),在这里应该可以看出此处使用的设计模式中的装饰模式。

从图中可以看出LocalFileSystem并没直接实现FileSystem,并且在hadoop权威指南中这样说的在hadoop的FS中继承了ChecksumFileSystem的FS才具有验证检验和的能力,不难想象,验证和的功能是在FilterFileSystem中完成的。看看源码就知道这种设计模式是策略模式,FilterFileSystem只对继承了FileSystem的类感兴趣。下面简单的看下ChecksumFileSystem和FilterFileSystem的构造函数。

ChecksumFileSystem

public ChecksumFileSystem(FileSystem fs) {
    super(fs);
  }

FilterFileSystem

 protected FileSystem fs;

  /*
   * so that extending classes can define it
   */
  public FilterFileSystem() {
  }

  public FilterFileSystem(FileSystem fs) {
    this.fs = fs;
    this.statistics = fs.statistics;
  }

从上面的三个类构造函数可以看出,RawLocalFileSystem的实例最终存储在FilterFileSystem的protected字段FileSystem fs中,然后调用FilterFileSystem的访问文件系统的相关方法实际上最后都避免不了调用字段fs对应的方法。so,hadoop中的FS继承了ChecksumFileSystem的就具有验证检验和的能力,例如还有InMemoryFileSystem也支持验证检验和。那么对于hadoop中其他的没有继承ChecksumFileSystem的文件系统该怎么支持验证检验和?从checkSumFileSystem和FilterFileSystem的构造函数不能看出,将任何一个继承了FileSystem的类包装下就可以实现验证检验和的功能。如想对DistributedFileSystem的实例添加验证检验和的能力,使用 new ChecksumFileSystem(dfs)就ok了,我把ChecksumFileSystem这个类称作文件系统的外套,披上了这层外套文件系统就变得更加强壮。

  以上的内容是对自己学习hadoop的阶段总结,我在这里抛砖引玉,有错误的地方希望大家帮忙指出哈。

hadoop文件系统体系

时间: 2024-10-13 19:29:12

hadoop文件系统体系的相关文章

Hadoop学习笔记(3) Hadoop文件系统二

1 查询文件系统 (1) 文件元数据:FileStatus,该类封装了文件系统中文件和目录的元数据,包括文件长度.块大小.备份.修改时间.所有者以及版权信息.FileSystem的getFileStatus()方法用于获取文件或目录的FileStatus对象. 例:展示文件状态信息 public class ShowFileStatusTest{ private MiniDFSCluster cluster; private FileSystem fs; @Before public void

将本地文件复制到复制到Hadoop文件系统

//将本地文件复制到复制到Hadoop文件系统 //目前,其他Hadoop文件系统写入文件时均不调用progress()方法. package com; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import org.apache.hadoop.co

hadoop文件系统浅析

1.什么是分布式文件系统? 管理网络中跨多台计算机存储的文件系统称为分布式文件系统. 2.为什么需要分布式文件系统了? 原因很简单,当数据集的大小超过一台独立物理计算机的存储能力时候,就有必要对它进行分区(partition)并存储到若干台单独计算机上. 3.分布式系统比传统的文件的系统更加复杂 因为分布式文件系统架构在网络之上,因此分布式系统引入了网络编程的复杂性,所以分布式文件系统比普通文件系统更加复杂. 4.Hadoop的文件系统 很多童鞋会把hdfs等价于hadoop的文件系统,其实ha

显示Hadoop文件系统中一组路径的文件信息

//显示Hadoop文件系统中一组路径的文件信息 //我们可以用这个程序来显示一组路径集目录列表的并集 package com; import java.io.IOException; import java.net.URI; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileSystem; import org.

使用seek()方法,将Hadoop文件系统中的一个文件在标准输出上显示两次

//使用seek()方法,将Hadoop文件系统中的一个文件在标准输出上显示两次 package com; import java.io.IOException; import java.net.URI; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FileSystem; import org.apac

hadoop2.5.2学习及实践笔记(六)—— Hadoop文件系统及其java接口

文件系统概述 org.apache.hadoop.fs.FileSystem是hadoop的抽象文件系统,为不同的数据访问提供了统一的接口,并提供了大量具体文件系统的实现,满足hadoop上各种数据访问需求,如以下几个具体实现(原表格见<hadoop权威指南>): 文件系统 URI方案 Java实现 (org.apache.hadoop) 定义 Local file fs.LocalFileSystem 支持有客户端校验和本地文件系统.带有校验和的本地系统文件在fs.RawLocalFileS

hadoop学习笔记:hadoop文件系统浅析

1.什么是分布式文件系统? 管理网络中跨多台计算机存储的文件系统称为分布式文件系统. 2.为什么需要分布式文件系统了? 原因很简单,当数据集的大小超过一台独立物理计算机的存储能力时候,就有必要对它进行分区(partition)并存储到若干台单独计算机上. 3.分布式系统比传统的文件的系统更加复杂 因为分布式文件系统架构在网络之上,因此分布式系统引入了网络编程的复杂性,所以分布式文件系统比普通文件系统更加复杂. 4.Hadoop的文件系统 很多童鞋会把hdfs等价于hadoop的文件系统,其实ha

hadoop文件系统简介

Hadoop文件系统简介 Hadoop家族中,最重要的两部分内容就是MapReduce和HDFS,其中MapReduce是一种编程范型,这种范型比较适合用来在分布式环境下进行批处理计算.另一部分就是HDFS,即hadoop分布式文件系统.Hadoop环境下可以兼容多种文件系统,包括本地文件系统,体现在文件系统API层面上就是有一个文件系统接口,这个接口可以有多种实现,包括本地文件系统或者分布式文件系统等. 一:HDFS的设计目标 HDFS是用来将数据存储到多台计算机上(计算机集群)为主要设计目标

直接使用FileSystem以标准输出格式显示hadoop文件系统中的文件

package com.yoyosys.cebbank.bdap.service.mr; import java.io.IOException; import java.io.InputStream; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IO