hadoop源码分析系列(三)——org.apache.hadoop.fs包 ----(下)

来源:互联网 发布:js计算时间差天数 编辑:程序博客网 时间:2024/05/20 01:09
摘要: 上一遍分析了fs子包中的源码,这一篇主要分析fs包下的类的源码首先分析下这个包中较为孤立的类抽象类FSOutputSummer类是OutputStream类的子类,主要作用是在调用底层的output输出流之前先生成数据的校验和, ...
上一遍分析了fs子包中的源码,这一篇主要分析fs包下的类的源码
首先分析下这个包中较为孤立的类
1.png
2.png
抽象类FSOutputSummer类是OutputStream类的子类,主要作用是在调用底层的output输出流之前先生成数据的校验和,构造方法中指定了可以根据指定数据的校验和、存储校验和的数据大小和数据分片的大小来初始化,由于不是直接写文件流的类,所以没有实现writeChunk方法,主要的方法有一下几个:
write(int b):写出一个int
write1(byte b[], int off, int len) :写出b中从off开始的len长度的子数组,同时最多刷新buffer一次,并为这段输出流生成校验和
flushBuffer(boolean keep):强制刷新缓冲区
writeChecksumChunk(byte b[], int off, int len, boolean keep):为数据分片生成校验和同时把数据和校验和交给底层的输出流

FsShellPermissions类是处理一些shell命令的改变权限问题,和FsShell的功能一样,只不过是为了减少FsShell的代码量,所以单列出了一个处理类,主要处理chmod、chown、chgrp三个命令。

FileUtil:处理文件的工具类。提供了对文件的拷贝、删除、chmod、拷贝合并、替换、解压等一系列操作

DU是shell的子类,作用和unix的du命令一样,是统计文件系统的已用空间,通过执行du -sk命令来得到结果

DF是shell的子类,作用和unix的df命令一样,是统计文件系统的已用空间,通过执行df -k命令来得到结果

ChecksumException是封装checksum时出现的异常

FsUrlStreamHandlerFactory:URL流处理工厂,具体的作用要使用java.net.URL的 setURLStreamHandlerFactory()方法设置URLStreamHandlerFactory,这时需要传递一个 FsUrlStreamHandlerFactory。这个操作对一个jvm只能使用一次。

LocalDirAllocator:本地目录分配器,在创建文件的时候轮询做空间的分配,其中最主要的方法是:
getLocalPathForWrite,原理类似于车轮,就是创建一个循环数组,然后在可用路径上进行前滚,知道找到能满足数据写入的空间

BlockLocation:记录block的元数据信息,如所在host,长度和偏移量

ContentSummary:记录文件或是目录的元信息

GlobExpander:完成对文件通配符的转换

FsUrlConnection:通过url打开一个inputStream

FsUrlStreamHandler:根据给定的配置信息通过url来访问文件系统

FSError:记录文件系统或是磁盘的错误



下面是将围绕FileSystem抽象类来分析fs包中剩余类的源码:
FileSystem类作为fs包中最重要的类定义了一系列对文件系统的操作,如创建删除,重命名等等
静态内部类Cache用来缓存文件系统中的对象信息,实现的机制就是map,键类Key主要保存了scheme、authority和username的信息
这些信息都是从uri或是配置对象中取得的,Cache类中还定义了三个同步方法用来解决缓存的获取、关闭和删除的并发问题,还实现了一个
线程,在虚拟机dead的时候清理缓存中的信息。

Statistics内部类记录了文件系统的统计信息,包括scheme信息和读写字节数

GlobFilter类实现了路径过滤的功能,其中accept方法判断了给出的路径是否能通过模式匹配


FileSystem类的创建方法主要有:
3.png

FSDataOutputStream create(FileSystem fs,
      Path file, FsPermission permission):在给定文件系统下的路径下创建指定权限的文件,返回对文件的输出流
createFileSystem(URI uri, Configuration conf
      ):根据指定的uri和配置信息创建文件系统
FSDataOutputStream create(Path f,
      FsPermission permission,
      boolean overwrite,
      int bufferSize,
      short replication,
      long blockSize,
      Progressable progress):在指定的path下创建文件,返回data的输出流,注意这里的参数包括了是否覆盖、缓冲区大小
冗余份数、块大小和进度信息

获取方法主要有:
4.png

可以通过配置对象、uri获得filesystem,也可以通过其他方法获得文件系统对于的配置信息、统计信息等
类里面值得注意的方法还有:
5.png

这个几个拷贝方法是相信用的比较多,具体的含义从方法名中很容易看出来,这几个方法的底层实现都是通过
FileUtil的copy方法实现的
6.png

这些方法用来获得文件系统的元数据信息



FileSystem的几个实现类:
7.png
其中4个之前已经分析过了,下面看剩下的两个:

FilterFileSystem:对进行文件系统操作的请求进行过滤,然后把符合规则的请求交给FileSystem来处理,方法基本也都是FileSystem中的方法。

HarFileSystem继承了FilterFileSystem,har文件设计的初衷是解决hdfs中大量小文件产生的问题,比如大量的小文件会大量消耗hdfs中的inode信息,文件越多对namenode的内存消耗越大。
这个文件系统有index文件和part-*文件组成,索引文件存储了真实文件的索引,索引文件有两种形式:_masterindex和_index,前者可以使索引文件的查询更快,后者存储了路径的hashcode
基本属性:
8.png
archiveIndex:索引文件的路径
archivePath:相关的文件系统的路径
harAuth:授权信息
masterIndex:master索引文件路径
underLyingURI:相关的uri
uri:har文件的uri
version:版本信息

下面分析几个最主要的方法:
initialize(URI name, Configuration conf):初始化har 文件系统,home目录为fs的最顶层目录:如
har://underlyingfsscheme-hostort/archivepath.
或者
har:///archivepath
方法的细节:1、找到正确的存储路径 2、初始化新的属性信息 3、从masterIndex中获得版本信息
decodeHarURI(URI rawURI, Configuration conf):把原始的uri编码为相关的har uri
getPathInHar(Path path):获得指定路径下的har文件
内部静态类HarFSDataInputStream采用FSInputStream方式完成了底层文件流的操作,文件输出流的操作目前在这个版本中只声明了方法并没有做具体实现
内部静态类HarStatus通过读取索引文件中的信息来获得har的状态
getFileBlockLocations(FileStatus file, long start,long len):从fs中获得文件block的信息,步骤是1、先确定是har fs 2、在索引文件中查询har文件状态 3、根据文件状态和起始块、长度值获得块的位置

RawLocalFileSystem类实现了fs的一个原生的本地的文件系统,可以通过这个类操作本地文件系统
这个类的实现比较简单,很多对文件的操作是通过执行本地操作系统的命令来完成的
URI NAME = URI.create("file:///"可以看出这是有别有hdfs://访问方式的本地文件系统访问方式,内部类LocalFSFileInputStream和LocalFSFileOutputStream通过InputStream和OutputStream来完成对文件流的操作,Syncable接口定义的sync方法可以同步所有的buffer。
原创作品 转载请注明出处   http://f.dataguru.cn/thread-19131-1-1.html