文件系统技术内幕:大数据时代海量数据存储之道
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.1.1 普通用户角度的文件系统

大家对文件系统的了解可能还是比较抽象,我们看一个Windows中文件系统的实例。在Windows中,通常大家不太清楚文件系统为何物。因为,一般安装Windows时都是一键安装,安装完成后磁盘已经被格式化(格式化是对硬盘、优盘或其他块设备进行初始化的过程)。通过Windows的资源管理器,我们只需要移动鼠标就能实现文件的所有操作。所以,我们通常并不会感知到在Windows中还有文件系统的存在。

如图1-2所示,这些文件夹与文件都是存储在磁盘上的,但我们并不知道具体磁盘空间是什么样的,文件系统软件呈现出来一个非常清晰的表象,我们可以非常容易地创建、删除和复制文件夹与文件。而这些功能是通过一个软件实现的,这个软件就是文件系统。

图1-2 Windows资源管理器

不仅在Windows中可以通过鼠标实现对文件系统的管理,而且在Linux中也可以通过鼠标实现对文件系统的管理。图1-3所示为Ubuntu(一个以桌面应用为主的Linux操作系统)中的GUI管理界面,可以看出其管理方式与Windows非常类似。

图1-3 Ubuntu中的GUI管理界面

目前,主流操作系统的文件系统数据组织形式大致都是这样的。在目录下面有子目录和文件,子目录下面又有子目录和文件,形成一个层级的树形结构。这种方式非常方便用户实现对文件的分类管理。以Linux为例,最终形成的层级目录树形结构如图1-4所示。

图1-4 层级目录树形结构

这种树形结构的数据组织方式是非常实用的。通过目录可以实现对内容的分类管理,而主类又可以包含子类。这在现实中有很多类似的场景,如公司销售按照区域管理客户资料。如图1-5所示,在每个目录中存储不同省份的客户资料;而每个省份又划出为不同的地区。通过这种层级结构,非常便于用户管理资料。

图1-5 公司客户资料层级结构

同时还需要说明的是,文件系统对文件进行了抽象化处理,对文件系统而言,所有文件都是字节流,它并不关注文件的格式与内容。文件的格式是由具体的应用软件来负责的。例如,文本文件由文本编辑软件来处理(如vim);图片文件则由图片浏览工具或编辑工具来处理(如Windows中的画图工具)。只有具体的软件才会关注文件的格式和内容。

下面对文件系统常见的概念进行一些简要的介绍。

1.1.1.1 目录(Directory)的概念

前文已经提到过“目录”这个术语,但并没有解释。在文件系统中目录是一种容器,它可以容纳子目录和普通文件。目录就像日常生活中的文件夹一样,它可以容纳文件。在GUI终端中可以很容易地分辨出目录和普通文件的差别,目录的图标与日常生活中的文件夹也非常像。如图1-6所示,选中的home就是Linux下目录的图标。

图1-6 GUI终端中的目录与普通文件

在命令行中区分目录和普通文件就不太直观了,但也并不太困难。有些Shell会将目录和文件显示成不同的颜色,以方便用户区分目录和文件。另外,在属性中会有标识,如图1-7所示,“唐山”这一目录最前面的字符为d,这个d就是directory的缩写,因此我们可以通过第1个字符来区分目录和文件。

图1-7 Shell中的目录与普通文件

如果深入了解了目录的实现原理,就会知道其实目录本身也是一种文件。只不过目录中存储的数据是特殊的数据,这些数据就是关于文件名称等元数据(管理数据的数据)的信息。以“河北”目录为例,其中存储的数据其实是文件名与一个数字的对应关系,如图1-8所示,这个数字就是所谓的inode ID。在文件系统层面中,普通用户通过文件名读取数据的过程需要这种映射关系。

图1-8 目录中的数据格式示意图

1.1.1.2 文件(File)的概念

在文件系统中,最基本的概念是文件,文件是存储数据的实体。从用户的角度来看,文件是文件系统中最小粒度的单元。文件的大小不是固定的,最小可以是0字节,最大可以是几十太字节(根据具体文件系统而定)。

为了便于用户对文件进行识别和管理,文件系统为每个文件都分配了一个名称,称为文件名。文件名就好像人名一样,它是一个标识。比如,我们去学校找张三,让班主任帮忙把张三叫出来,此时班主任就能通过人名很容易找到张三。

文件系统也是这样,当普通用户想要访问某个文件时,告诉文件系统自己想要访问的文件名,此时文件系统就可以根据文件名找到该文件的数据。比如,在Windows中双击某个视频或图片文件,那么就有相应的软件将其打开。底层原理方面就涉及文件系统对文件数据查找的流程。

文件名通常包含两部分,并通过“.”进行了分隔,但并非绝对。以图1-9中的test1.jpg文件为例,该文件名可以分为两部分:第一部分称为文件主名,它表示该文件的标识,就好像人名一样;第二部分称为扩展名,它的作用是标识文件的类型。这种命名方式便于用户能够对文件有一个快速的整体认识。比如,我们可以一眼就能知道某个文件存储的是视频、音频还是图片。

图1-9 文件名的格式

下面进一步介绍文件的内部。从普通用户(开发人员)的角度来看,文件就是一个线性空间,这就好比程序开发中的数组一样。与数组不同的是文件的大小是可以变化的,当写入更多的数据时,文件的容量就会变大。虽然文件数据以普通用户角度来看是线性的、连续的,但是在文件系统层面并非如此。其真实位置可能在磁盘的任意位置。如图1-10所示,一个文件通常在逻辑上被划分为若干等份,每一份被称为一个逻辑块(Block)。文件的逻辑块在磁盘中的物理位置并不固定,逻辑块是连续的,物理块却可能散布在很多地方。

图1-10 文件数据的组织形式

对文件系统而言,它并不关心文件是什么格式的,而是把所有文件看作字节流。但是在普通用户层面需要关心文件的格式。因为,不同格式的文件需要使用不同的工具访问。对Windows和桌面版的Linux而言,操作系统层面建立了文件格式与软件的关联,因此当双击文件的图标时就会自动使用对应的软件打开该文件。但也不一定,因为有时可能系统缺少相关的软件,或者关联关系被破坏,此时就无法打开该文件。

文件格式的种类非常多,如常见的.txt、.pptx、.docx或.mp3等,都由特定的工具软件打开。.mp3格式的文件只有通过播放器软件打开才有意义,才可以播放音乐。如果使用文本编辑工具打开一个.mp3格式的文件,看到的只能是一堆乱码。

1.1.1.3 链接(Link)的概念

链接是Linux文件系统的概念,在Windows和macOS中通常被称为快捷方式。Linux中的链接分为软链接(Soft Link)和硬链接(Hard Link)两种。其中,软链接又被称为符号链接(Symbolic Link),它是文件的另外一种形态,其内容指向另外一个文件路径(相对路径或绝对路径)。硬链接则不同,它是一个已经存在文件的附加名称,也就是同一个文件的第2个或第N个名称。

为了更加直观地理解软链接和硬链接的概念,在test目录中创建一个源文件src_file.txt。同时为该文件分别创建一个软链接(softlink.txt)和一个硬链接(hardlink.txt)。然后使用ls命令查看该目录的详细信息,如图1-11所示。

图1-11 文件的软链接与硬链接

通过上面的结果可以看出,软链接有一个“->”符号,该符号指示了该链接所指向的目的文件。而硬链接并没有“->”符号,也就是我们无法明确地知道哪个是硬链接的目的文件。但是如果我们观察一下硬链接与源文件最前面的数字就会发现是一样的。这个数字是inode ID,说明它们是指向同一个文件的。

从原理上来理解,硬链接其实是在目录中增加了一项,而该项的inode ID是源文件的inode ID。因此硬链接与源文件的内容是完全一样的。

那么链接的作用是什么呢?主要是为了实现对源文件的快速访问,并且节省存储空间。在有些情况下,我们需要在B目录使用A目录中的某个文件。这时使用链接要比复制功能更加方便、合适。因为通过链接的方式,在源文件发生变化的情况下可以马上感知,不需要重新复制,同时又节省存储空间。

为了更加直观地理解链接的作用,通过图1-12的实例进行简要介绍。以培训机构教学为例。假设已经有一个教学素材库,有很多素材在目录data中。某学期需要开始一个新的课程,该课程要用到素材库中的一个视频文件。该课程的素材都在course目录中。此时就可以在course目录中建立一个到素材库的链接。这样course目录中既包含了该视频,又不会占用太多存储空间。另外,即使对素材库中的视频文件进行了修改,course目录中也只是一个链接,因此其内容也会跟着修改,不会出现不一致的情况。

图1-12 链接的使用示意图