划重点:存的时候必须记录一些关键信息(记录ID、给身份牌),取的时候才能正确定位到 。
文件系统
回到我们的文件系统,对比上面的行李存取行为,可以做个简单的类比;
- 登记名字就是在文件系统记录文件名;
- 生成的牌子就是元数据索引;
- 你的行李就是文件;
- 寄存室就是磁盘(容纳东西的物理空间);
- 管理员整套运行机制就是文件系统;
划重点:文件系统的存储介质是磁盘,文件系统是软件层面的,是管理员,管理怎么使用磁盘空间的软件系统而已 。
空间管理
现在思考文件系统是怎么管理空间的?
如果,一个连续的大磁盘空间给你使用,你会怎么使用这段空间呢?
直观的一个想法,我把进来的数据就完整的放进去 。

文章插图
这种方式非常容易实现,属于眼前最简单,以后最麻烦的方式 。因为会造成很多空洞,明明还有很多空间位置,但是由于整个太大,形状不合适(数据大小),哪里都放不下 。因为你要放一个完整的空间 。
这种不能利用的空间我们称之为碎片,准确的说是外部碎片,这种碎片在内存池分配内存的时候最常见,产生的原理是一样的 。
怎么改进?有人会想,既然整个放不进去,那就剁碎了呗 。这里塞一点,那里塞一点,就塞进去了 。
对,思路完全正确 。改进的方式就是切分,把空间按照一定粒度切分 。每个小粒度的物理块命名为 Block,每个 Block 一般是 4K 大小,用户数据存到文件系统里来自然也是要切分,存储到每一个 Block。Block 粒度越小则外部碎片则会越少(注意:元数据量会越大),可以尽可能的利用到空间,并且完整的用户数据文件存储到磁盘上则不再连续,而是切成一个个 Block 大小的数据块存到磁盘的各个角落上 。

文章插图
图示标号表示这个完整对象的 Block 的序号,用来复原对象用的 。
随之而来又有一个问题:你光会切成块还不行,取文件数据的时候,要给完整的用户数据出去,用户不管你内部怎么实现,他只想要的是最初的样子 。所以,要有一个表记录该文件对应所有 Block 的位置,要把每一个 Block 的位置记录好,取文件的时候,对照这表恢复出一个完整的块给到用户 。
所以,写流程再完善一下就是这样子:
- 先写数据:数据先按照 Block 粒度存储到磁盘的各个位置;
- 再写元数据:然后把 Block 所在的各个位置保存起来,这也就是元数据,文件系统里叫做 inode(我用一本书来表示);

文章插图
文件读流程则是:
- 先读元数据,找到各个 Block 的位置;
- 然后读数据,构造一个完整的文件,给到用户;

文章插图
inode/block 概念
好,现在我们引出了两个概念:
- 磁盘空间是按照 Block 粒度来划分空间的,存储数据的区域全都是 Block,我们叫做数据区域;
- 文件存储不再连续存储在磁盘上,所以需要记录元数据,这个我们叫做 inode;
block 固定大小,每个 4k(大部分文件系统都是,这里不做纠结),block 意图存储打散的用户数据 。
无论是 inode 区,还是 block 区,本质上都是在线性的磁盘空间上 。文件系统的空间层次如下:

文章插图
推荐阅读
- Linux查看硬件信息超强命令sar,以及可视化工具ksar
- 微信正在用的深度学习框架开源!支持稀疏张量,基于C++开发
- PC电脑|5分钟开机上千台 无影云电脑免费体验1周:Win、Linux通吃
- linux内核SMP负载均衡浅析
- 浅谈在Linux中如何将脚本做成系统服务开机自启动
- 寒湿型肥胖喝什么茶,喝什么茶排寒湿深度好文
- Linux服务器磁盘满了怎么办
- 色相饱和度深度解析,photoshop明度观察层是什么?原理讲解
- linux安装php步骤详解
- 「linux专栏」top命令用法详解,再也不怕看不懂top了
