第5章 Hadoop 文件系统
1.文件及文件系统
文件的本质是存储在设备上的线性字节流
文件系统用于文件的管理包括文件的结构以及命名、存取、使用、保护和实现
文件系统支持的系统调用:
1) 创建文件
2) 删除文件
3) 打开文件
4) 关闭文件
5) 读文件
6) 写文件
7) 追加数据
8) 读记录
9) 写记录
10) 删除记录
11) 移动当前位置
12) 获取文件属性
13) 设置文件属性
14) 文件改名
目录树组织文件系统,路径名描述文件系统中文件的位置,用/隔开
文件系统管理目录的系统调用:
1) 创建目录
2) 删除目录
3) 打开目录
4) 关闭目录
5) 读目录
6) 目录改名
Unix文件系统操作:
1) 加载文件系统(mount)
2) 卸载文件系统
文件系统的实现
1) 块管理:以随机存储设备为例,有三种方式实现块管理
1.1) 连续分配:类似于数组,需要预先知道块大小
1.2) 链接表:顺序读取方便但随机存储效率低
1.3) 索引链式表:需要把整个链表存放在内存中
2) 目录管理:目录数据由结构化的记录组成,每个记录描述了集合中的一个文件或者子目录
3) 存储媒体上的文件系统管理
4) 存储空间管理
存储控制验证模块:
1) 审定用户的存储权限
2) 比较用户权限与本次存取要求是否一致
3) 将存取要求和被访问文件的保密性比较,看是否有冲突
验证用户存取操作:
1) 口令
2) 密码(加密)
3) 存取控制矩阵
4) 存取控制表+权限表
2. Linux文件系统(Ext2,Ext3)
ext2_inode{//文件和目录的元数据
i_mode;//文件类型和访问权限
i_uid;//拥有者标识符
i_size;//以字节为单位的文件长度
i_atime;//最后一次访问文件时间
i_ctime;//索引节点最后改变时间
i_dtime;//文件删除时间
i_gid;//用户组标识符
i_links_count;//硬链接计数器
i_block;//文件的数据块数
i_flags;//文件标识
}
文件管理器查找特定文件过程:(/home/cq/test.txt)
1) 寻找根目录对应的i-node(2号i-node),在2号i-node中找到块编号
2) 在块编号中找到home对应的目录项得到i-node 8,在i-node 8上找到块编号132
3) 块132上找到cq的目录项对应的i-node 30,在i-node 30上找到块编号406
4) 块406上找到test.txt的目录项对应的i-node 92,即得到了text.txt的元数据
2.1 虚拟文件系统(VFS)
面向对象的思维发展起来,在内核中的软件层,为上层应用提供文件系统接口,并隐藏了底层文件系统的具体实现细节,应用程序对文件系统进行操作时,内核文件系统首先调用VFS的相应接口函数,处理与文件系统无关的操作,然后再调用真正的文件系统中的函数处理与设备相关的操作
2.2 Linux文件保护机制
文件的用户分为:拥有者,用户组,其他
文件的读、写和执行权限:r,w,x
目录的读、写和执行权限:r(读取文件夹内容列表),w(修改目录的内容包括创建文件或者文件夹,删除文件或者文件夹,对已存在的文件或者文件夹改名和更改目录内文件或者文件夹的位置)w(可执行)即可以进入目录
2.3 Linux文件系统API
文件I/O函数:open(),read(),write(),close()和lssek()
文件/目录函数:stat(),chmod(),chown(),utime
目录树的操作:opendir(),readdir(),seekdir(),closedir()
进程工作目录操作:getcwd(),getwd(),chdir
3. 分布式文件系统
特性:
1) 访问透明性
2) 位置透明性
3) 移动透明性
4) 性能透明性
5) 伸缩透明性
6) 复制透明性
7) 故障透明性
8) 并发透明性
9) 数据完整性、安全性和系统异构
典型的分布式文件系统NFS(C/S模型),与Linux所提供的文件系统模型一致:文件解释为字节序列,目录树组织,文件有文件名,通过类似Linux文件句柄访问
4. Java文件系统(java.io.File)
4.1 文件系统API
File file=new File(“”);//创建文件对象
file.exists();//判断文件是否存在
file.isDirectory();//判断是否为目录
file.isFile();//判断是否为文件
file.createNewFile();创建该文件
file.mkdir();;//创建目录
file.list();//获得该目录下的所有文件名的数组
file.delete();//删除文件或者目录
file.deleteOnExit();//虚拟机一旦退出就删除
file.renameTo();//修改文件名(移动文件)
file.canRead();//是否可读
file.getCannonicalFile();返回包含文件规范路径(绝对路径)的File对象
String currentdir=System.getProperty(“user.dir”);//返回用户进程的当前工作目录
UnixFileSystem or Win32FileSystem->FileSystem->File
FileSystem封装了具体文件系统的实现细节,即不关心底层文件系统是Unix还是Win32,比如file.renameTo()实际上进行一定的安全检查之后通过FileSystem fs静态成员变量调用rename()实现文件的重命名
4.2 URI和URL
file.toURI();//将文件对象转化为对应的URI(统一资源标识符)
绝对URI由URI模式和模式特有部分组成
URI uri=new URI(String str);
常用的模式包括:
1) 本地磁盘文件:”file:/E:/”
2) 万维网服务器:http://www.hzbook.com
3) 文件传输服务器:”ftp://user1:[email protected]:80/hadoopInternal/chart2.pdf“
4) 电子邮件地址:“mailto:[email protected]”
5) 基于Telnet协议的服务连接
6) Hadoop中的hdfs,har,s3,kfs等标识不同资源
两种类型的URI:
1) URL(统一资源定位符)
2) URN(统一资源名)
URL基本格式:
协议://用户信息@主机名:端口/路径?查询#片段
URL url=new URL(String str); //创建一个指向Internet上的实际资源的URL
InputStream is=url.openStream();//用于读取远程资源
随机存取文件
RandomAccessFile raf=new RandomAccessFile(pathor file,mode);//第一个参数既可以是文件路径又可以是文件对象,mode则标识文件可执行的操作r(只读)、wr(读写)
raf.getFilePointer();//返回文件指针位置
raf.seek(long pos);;//文件指针设置在pos字节位置
5. Hadoop抽象文件系统(org.apache.hadoop.fs.FileSystem)
5.1 Hadoop抽象文件系统的基本API:
1) FileSystem.open();
FileSystem.create();
FileSystem.append();//打开文件
2) FSDataInputStream.read();//读取文件内容
3) FSDataOutputSream.write();//写文件
4) FSDataInputStream.close();
FSDataOutputStream.close();//关闭文件
5) FSDataInputStream.seek();//改变文件读写位置
6) FSDataInputStream.getPos();//返回文件的当前读写位置
7) FileSystem.getFileStatus();//获取文件/目录属性,包括文件路径path,文件长度length,是否为目录isdir,副本数block——replication,块大小blocksize,最后修改时间modification_time,最后访问时间access_time,许可信息permission,文件所有者owner,用户组group
8) FileSystem.createNewFile();//创建文件
9) FileSystem.delete();//删除文件
10) FileSystem.rename();//重命名文件
11) FileSystem.mkdirs();//创建目录
12) FileSystem.listStatus;//读取目录下的项目
13) FileSystem.getWorkingDirectory();//返回当前工作目录
14) FileSystem.setWorkingDirectory();//设置当前工作目录
15) FileSystem.setReplication();//设置文件副本
16) FileSystem.getReplication();//返回文件副本
17) FileSystem.getContentSummary();//相当于du、df命令提供的功能
5.2 Hadoop输入/输出流
FSDataInputStream继承于jdk中的DataInputStream,实现了Seekable、PositionedReadable、java.io.Closeable
Seekable.seekToNewSource();//选择其他副本
PositionedReadable().readFully();//读取指定长度的数据,直至缓冲区满或者流结束为止
FSDataOutputStream继承于DataOutputStream,PositionCache是前者的内部类且是前者的子类,重载了write()跟踪目前流的写位置。;实现了Syncable接口(唯一函数sync()目的是将流中的数据同步到设备中)
5.3 Hadoop文件系统中的权限
类似于Linux文件系统权限管理
public enum FsAction{
NONE(“---”),
EXECUTE(“--x),
WRITE(“-w-“_),
WRITE_EXECUTE(“-wx”),
READ(“r—“),
READ_EXECUTE(“r-x”),
READ_WRITE(“rw-“),
ALL(“rwx”)
}
FsAction.ordinal();//返回当前序数
FsAction.implies();//比较一种权限是否隐含另一种权限
public class FsPermission implementsWritable {//文件权限类
//POSIX permission style
private FsAction useraction = null;
private FsAction groupaction = null;
private FsAction otheraction = null;
}
public class PermissionStatus implementsWritable {//相对于FsPermission而言多包含用户username和用户组信息groupname
private String username;
private String groupname;
private FsPermissionpermission;
}
public class FileStatus implementsWritable, Comparable {//文件元信息
private Path path;
private long length;
private boolean isdir;
private short block_replication;
private long blocksize;
private long modification_time;
private long access_time;
private FsPermission permission;//文件权限
private String owner;
private String group;
private Path symlink;
}
5.4 抽象文件系统中的静态方法
FileSystem.get(uri,conf);//类似于工厂模式,创建或者返回uri指定的文件系统
FileSystem.getLocal(conf);//返回本地文件系统
CACHE.Key{
Scheme;//URI 模式
Authority;//URI authority
Unique;//unique默认0
Ugi;//ugi本地用户信息
}
FileSystem.get(uri,conf);//只有uri与Cache.Key中所有属性值相同,才允许共享文件系统实例(即直接Cache.get(uri,conf)从缓存中获取文件系统)
当需要创建一个被Cache管理且不被共享的具体文件系统时,FileSystem.CACHE.getUnique(uri,conf);
FileSystem.newInstance();//得到的文件系统实例永远不会被共享
5.5 Hadoop文件系统中的协议处理器
如何通过URL顺利打开一个特定URL模式的输入/输出流,包括协议处理和内容处理两部分
协议处理涉及C/S交互;内容处理则涉及将协议处理过程中获得的内容进行展现
Hadoop文件系统中协议处理包括FsUrlStreamHandler,FsUrlConnection,FsUrlStreamHandlerFactory
Hadoop协议处理的过程:
URL url=new URL(“hdfs://example:port/”)->URL.setURLStreamHandlerFactory(newFsUrlStreamHandlerFactory())//接收hdfs协议并寻找适当的URLStreamHandler->FsUrlStreamHandler//创建hdfs的流处理器对象并保存在URL对象的内部成员中->流处理器对象解析URL字符串,创建于服务器通信的FsUrlConnection->url.openStream()实际上是FsUrlConnection.getInputStream()
5.6 Hadoop具体文件系统
FileSystem->FilterFileSystem->ChecksumFileSystem->ChecksumDistributedFileSystem,InmemoryFileSystem,LocalFileSystem
ChecksumFileSystem为文件保存对应的校验信息文件,并在读文件时进行校验
FileSystem->FilterFileSystem->HarFileSystem
HarFileSystem将小文件归档成大文件,使得构建于Hadoop MapReduce的应用可以访问Hadoop归档文件,处理大量小文件输入
Hadoop的具体文件系统
文件系统 |
URI模式 |
实现 |
描述 |
本地 |
file |
fs.LocalFileSystem fs.RawLocalFileSystem |
前者支持数据校验 后者不支持 |
HDFS |
hdfs |
hdfs.DistributedFileSystem |
Hadoop分布式文件系统 |
HFTP |
hftp |
hdfs.HftpFileSystem |
HDFS集群间复制数据 |
HSFTP |
hsftp |
hdfs.HsftpFileSystem |
安全性更高 |
HAR |
har |
fs.HarFileSystem |
存档文件系统 |
KFS |
kfs |
fs.kfs.KosmosFileSystem |
分布式文件系统 |
FTP |
hdfs |
fs.ftp.FTPFileSystem |
FTP协议支持的文件系统 |
简单S3 |
s3n |
fs.s3native.NativeS3FileSystem |
读写存放在S3上的数据 |
本地S3 |
s3 |
fs.s3.S3FileSystem |
由S3支持的文件系统 |
内存 |
ramfs |
fs.RawInMemoryFileSystem fs.InMemoryFileSystem |
内存文件系统 |
5.7 RawLocalFileSystem
mkdirs(Path path);//递归创建目录,实质上调用了java.io.File.mkdir()
listStatus(Path path);//若path对应的是文件,则直接创建包含该文件元信息的RawLocalFileStatus元素数组;否则获得该目录下的所有文件和子目录的元信息的RawLocalFileStatus元素数组
读写文件:
LocalFSFileInputStream和LocalFSFileOutputStream
LocalFSFileInputStream.seek(long pos);//移动文件当前位置
LocalFSFileInputStream.getPos();//当前读写文件位置
修饰器模式
5.8 ChecksumFileSystem的实现
在ChecksumFileSystem中,如果有文件”example.txt”那么该文件的CRC-32校验信息保存在文件”.example.txt.crc”中
ChecksumFileSystem.getChecksumFile(Pathfile);//返回对应的校验文件
ChecksumFileSystem.isChecksumFile(Path file);//判断是否为校验文件
ChecksumFileSystem.rename(Path src,Path dst);//若src为目录,则直接改名;若src是文件则先对src改名,然后对src对应的校验文件改名
写文件
ChecksumFSOutputSummer实现数据文件和校验信息文件的输出,继承自org.apache.hadoop.fs.FSOutputSummer
ChecksumFSOutputSummer(ChecksumFileSystemfs,Path file,Boolean overwrite,int bufferSize,short replication,longblockSize,Progressable progress);//构造方法创建两个输出流,分别用于输出文件数据和输出文件数据的校验和
FSOutputSummer.write()调用write1(0->调用writeChecksumChunk()->调用writeChunk()写入文件数据和文件数据校验和
读文件
ChecksumFSInputChecker继承自FSInputChecker
ChecksumFSInputChecker()//构造方法,打开输入流datas和sums,还需要进行一系列的检查和配置
FSInputChecker.read()调用read1()->调用readChecksumChunk()->调用readChunk()读入原始数据和校验数据->调用verifySum()进行数据校验
5.9 RawInMemoryFileSystem的实现
RawInMemoryFileSystem是InMemoryFileSystem的内部类,继承自FileSystem
基本属性:
fsSize:文件系统预留空间
totalUsed:目前已使用空间
Map
Map
RawInMemoryFileSystem.open(Path path,intbufferSize);//返回FSDataInputStream对象调用read()便可以读数据