正如解决数学问题通常我们会谈“思想”,诸如反证法、化繁为简等,解决计算机问题也有很多非常出色的思想。思想之所以称为思想,是因为“思想”有拓展性与引导性,可以解决一系列问题。根据我自己的学习体验,解决计算机科学问题有三个非常重要的思想:虚拟、缓存、分层。
这些思想的应用可以在计算机科学的各个方面找到。计算机科学的文件系统的构成充分体现了这三个思想的应用;这篇文章以小见大,来说明文件系统是如何体现这三个思想的。
虚拟
虚拟的思想很像数学中的“抽象”的思想。虚拟通过将结构、性质不同的底层实现进行封装,向上提供统一的API接口,让使用者觉得就是在使用一个统一的资源,或者让使用者觉得自己在使用一个本来底层不直接提供、“虚拟”出来的资源。
虚拟文件系统(VFS, Virtual File System)是一个分层结构。向下统一设备I/O等硬件资源,向上提供统一的文件/文件系统API,让用户觉得自己用的就是一套统一的文件系统。例如,在unix系统中,“一切都是文件”就是这种虚拟文件系统思想的体现。
虚拟文件系统主要由三部分构成:
- 文件卷控制块
- 文件控制块
- 目录项
其结构如下图所示:
当文件系统挂载的时候,文件卷控制块就加载到挂载点;当访问某个文件时,文件控制块就被加载到内存;目录项只会在做遍历等操作时才会加载。这些信息都会被持久存在外存中。(磁盘中有一部分空间用来储存这些信息)
在这个统一的框架下,不通类型的文件系统(例如磁盘文件系统FAT,NTFS,数据库文件系统WinFS,日志文件系统,网络文件系统等)与不同结构的文件(字节序列、简单记录结构、复杂结构如word等)就成为了这个虚拟文件系统的一个实例。例如,网络文件系统可能被挂载在/net/
下,当我们插入USB时,在/Volumns
中就挂载了USB介质。
缓存
缓存这个机制,非常巧妙地解决了读速度与写速度不一致的问题。计算机的虚拟内存、路由器的数据接收与发送等,都可以看成缓存思想的应用。
在文件系统中,由于从磁盘上读取是机械过程,速度比较慢,解决读写速度不一致问题的一个有效方案是缓存。基本思想是将磁盘中的数据读如磁盘控制器(扇区缓存),在一定条件下,将数据缓存到内存。
通常缓存数据块的情景有两种:
- 对数据有需求。因此计算机会将后面的数据块预先读如缓存。
- 数据块使用后将来还可能被用到。
缓存从方式上分可以分为两种:数据块缓存与页缓存。
在数据块缓存中,文件并不是直接缓存到内存中,而是被缓存到数据缓存块,页缓存也被缓存到数据缓存块,文件读写操作从数据缓存块读取文件数据;在页缓存中,文件缓存在内存中(可能是虚拟内存),文件的读写操作被缓存成对内存的访问。
通过这种方式,可以大大提高文件的读写速度。
分层
当一个问题比较复杂是,通常通过分层,每层利用下层API,实现一定功能,向上层提供更高级的API。这种思想有点类似数学中的多尺度(multiscale);许多问题在一个尺度下解决比较困难,但是通过多尺度,可以综合细网格与粗网格的优点,达到解决问题的目的。一个例子是网络的7层结构,通过不稳定的硬件,一层层封装,最终可以提供稳定的网络服务。
文件系统中,文件分配是一个典型应用分层思想的文件储存解决方案。由于一个文件系统中,文件的大小不相同,大多数文件都很小,分配的块空间不能太大,同时也要支持一些大文件(64位文件偏移),并且访问这些大小不同的文件时我们希望是高效的。
文件分配一般有三种方式:
- 连续分配
在这种方式中,文件被分配到一个连续的物理数据块空间。这种方式支持高效的随机访问,但是由于分配的是连续的磁盘空间,可能导致磁盘碎片。而且由于空间较为固定,增长文件也会出现问题。
- 链式分配
文件以数据块链表方式储存。这种方式下,创建、增大、减小文件很容易,但是随机访问代价比较高。稳定性也是一个问题:破坏一个链,可能导致其后的数据都丢失。
- 索引分配
索引分配的基本结构是
文件指针 --> 索引 --> 数据块1,数据块2,……
索引分配综合了上面两种分配方式的优点,但是如果文件比较小,储存索引的开销相比文件大小可能比较昂贵,如果文件比较大,索引可能无法放到一个索引块中,需要多个索引块,这增加了访问的难度。
Unix系统采用了UFS多级索引分配的方式
UFS有很好的尺度适应性:当文件比较小时,文件指针inode
直接指向文件数据块,当文件比较大时,索引块的数量增加的量级只是log(n)的量级。
通过分层的方式,UFS大大提高了文件大小的限制域值,动态分配数据块,小文件开销小,支持大文件。
另一种思想:分布式
上面的三种思想在计算机科学的许多方面都有体现,除了这些思想,另外还有一种常见的思想是分布式。谈及分布式,让人想起Hadoop等现在研究非常火热的分布式技术,事实上,分布式在文件系统中也有自己的体现。
分布式的基本思想是:
通过并行提高吞吐量,通过冗余来提高可靠性与可用性。
在文件系统中,磁盘阵列通过多磁盘管理来实现分布式。我们以RAID-0为例,文件系统将数据块分为多个字块,存储到独立的磁盘中,当读取数据的时候,可以同时读取这些磁盘的数据,从而通过并行提高了吞吐量。
RAID-1的方案是将数据同时写入两个磁盘,读数据时从任何一个读取,这样某个磁盘的数据丢失后,可以从另一个磁盘获得,这种方式是通过冗余来提高可靠性与可用性。
还有很多其他的RAID方案,其核心就是通过分布式来获得吞吐量、可靠性或两者。
总结
我们通过文件系统的一些方面说明了虚拟,缓存,分层思想在计算机科学中的应用,同时提及了分布式的思想。思想是各中计算机问题甚至各个学科共通的解决问题的利刃,我相信这些思想可以在更多的计算机科学问题甚至其他学科问题中发挥巨大的作用。