如何在一分钟内遍历一个100T的文件
学而时习之,不亦说乎!今天我们借着“如何在一分钟内遍历100T大小的文件”这个问题,重温一下与我们息息相关的文件系统,文件这个我们即熟悉又陌生的东西,为什么熟悉呢?因为我们在日常的开发中经常与文件打交道,又为什么陌生呢?因为我们不知道为什么会出现文件?或者我们是否思考过文件是什么呢?相信很多人都说文件是磁盘中的数据。这句话没有错,但是不够细节。我认为文件是操作系统表示磁盘数据的一种形式。我们可以借助文件向磁盘中写入数据,也可以借助文件向磁盘中读出数据。正是因为文件是一种访问数据的形式,所以在Linux中才提出了“一切皆文件”的思想。正如在编程语言中,我们通过变量访问内存中的数据,借此规避了使用内存地址访问内存中的数据,大大简化了操作内存中数据的复杂度,文件也不例外,因为有了文件,我们才不用利用硬盘地址去操作硬盘中的数据,也大大简化了操作硬盘的复杂度。我们可以说这是对使用者友好,但是操作硬盘的本质复杂度没有减低,只不过是文件系统帮我们承担的绝大部分复杂度而已。这里又不得不感叹世界的神奇,世界总是想通的,正如“哪有什么岁月静好,不过是有人在替你负重前行”一样。好,说回来,文件系统对外,提供简单的操作来操作硬盘数据,对内通过FCB来管理硬盘数据。那么什么是FCB呢?FCB 全称 File Control Block,即文件控制块,和PCB一样是文件的元信息,主要包括,文件的创建者,文件的更新时间,文件的大小,以及一张索引表。文件系统通过将磁盘分为多个块,来进行管理,一个文件块一般4K的大小,而FCB中的索引表就记录这有哪些文件块。因为FCB的大小是固定的,所以索引表的大小也是固定的,这就导致了一个文件存在最大容量,一般而言,FCB中的索引表有15个槽位,前12个位置直接存储数据块的地址,第13的位置存储的是一级索引的位置,即一级索引表,第14的位置存储二级索引的位置,第15的位置存储三级索引的位置,而一个索引块可以存储256个数据块,那么一个FCB最多可以使用数据块:(12 + 256 + 256256 + 256256*256 ),根据一个数据块4K的大小,大概可以存储64GB的数据,所以一个文件最大的容量为64G,这和标题所说的100T差的不是一星半点。而且硬盘分为固态硬盘以及机械硬盘,固定硬盘的数据也不过2000MB/s左右,机械硬盘也不过800MB/s左右,这距离一分钟也差的不是一星半点。文件的大小有限制,硬盘的速度有限制,那么我们应该怎么办呢?我们先来看看大佬们是如何突破硬盘速度的限制的?既然文件被分为很多个数据块,那如果我将数据块分别存储到多块不同的硬盘上,这样在读取这个文件时,就可以同时读取不同的硬盘,这样数据不就翻了几倍。这就是RAID0方案,但是这个方案有一个缺点,那就是可用性太差了,如果一块硬盘损坏那么这个文件就不完整了。于是就有了RAID1方案,核心思想就是备份,就是将原本的一个数据块复制成两个存储到不同的硬盘中。但是这样硬盘的利用率就只有50%了,于是就出现了新的改进方案RAID5,大致的逻辑就是将文件的数据块分为N-1组,然后利用位运算计算出1组校验数据,将这N组数据存储在不同的硬盘中。如果一块硬盘损坏,那么就可以利用这1组校验数据恢复。但是如果两块硬盘损坏就无能为力了,所以就有了RAID6方案,逻辑和RAID5差不多,只不过用来两种校验算法,这样在两块硬盘损坏时,就可以利用剩下的数据来恢复损坏的数据。
到此我们就利用RAID方案可以提升硬盘的速度,那如何突破文件大小的限制呢?答案是分布式文件系统,我们知道一个数据块的大小只有4K,一个索引表只有15个槽位,只要我们改大其中的一个,我们就可以突破文件大小的限制。一般我们会选择增大数据块的大小,因为索引表关系到文件系统,如果我们的分布式文件系统需要和本地文件系统做兼容的话,一般就不会改变索引表的结构。这样我们就可以很轻松的在1分钟内访问一个100T的文件了