一、文件系统介绍
数据在计算机中以二进制的方式存储在介质中的,但是我们并不能直接理解这些高低电平的数据代表什么意思,而文件系统就是告诉我们这些二进制的数据要表达的内容。文件系统将二进制的数据按照人类可理解的架构解析出来,这样我们可以通过这个系统来管理、删除和复制这些文件,从而来控制存储里面的数据。
打个比方,存储的磁盘就相当于我们的仓库,空间很大,让我们来存储数据使用。虽然我们可以直接将数据存储到磁盘的空间,但是由于缺少规划,我们数据可能就会毫无规律的存放在磁盘上。不但放的数据比较少,而且当我们想查找的时候也会非常费劲,甚至找不到需要的数据。因此文件系统就出现了。一方面将数据进行统一管理,另一方面让用户能够更好的查到数据。
在基于 Linux 系统下可以采用如下集中方式来查看当前挂载的文件系统:
1. mount 命令
$ mount |
上面的结果的释义可以按照如下表格来说明:
类型 | 挂载点 | 文件类型 | 挂载选项 |
---|---|---|---|
sysfs | /sys | sysfs | rw,nosuid,nodev,noexec,relatime |
proc | /proc | proc | rw,nosuid,nodev,noexec,relatime |
udev | /dev | devtmpfs | rw,nosuid,noexec,relatime,size=…,nr_inodes=…,mode=…,inode64 |
第一列的内容,有些是表明的文件系统如 sysfs、proc 等,有些是代表管理服务如 dev,它负责动态创建和删除设备节点,并根据设备的属性来设置这些节点的权限和所有者。挂载点代表的是实际的文件目录,挂载选项含义如下所示:
- rw : 读写模式
- nosuid : 不允许设置用户ID
- nodev : 不允许作为设备文件
- noexec : 不允许执行二进制文件
- relatime : 更新文件的时间戳,但仅当文件被修改时才更新
- size : 文件系统的大小
- nr_inodes : 文件系统中inode的数量
- mode : 文件系统的权限模式
- inode64 : 支持64位inode
- gid : 设置组ID为5
- ptmxmode : 控制伪终端的权限
- errors : 控制发生错误时的行为
2. findmnt 指令
findmnt 命令将列出所有已挂载的文件系统或者搜索出某个文件系统。findmnt 命令能够在 /etc/fstab、/etc/mtab 或 /proc/self/mountinfo 这几个文件中进行搜索。findmnt 预装在大多数的 Linux 发行版中,因为它是 util-linux 包的一部分。如果 findmnt 命令不可用,可以安装这个软件包:
sudo apt install util-linux |
查找内容如下:
$ findmnt |
3. df 指令
$ df -T |
其中:
- Filesystem : 文件系统的设备名或标识符
- Type : 文件系统的类型
- 1K-blocks : 文件系统中的块数,以千字节(1K)为单位
- Used : 已使用的块数,同样以千字节为单位
- Available : 可用的块数,以千字节为单位
- Use% : 使用百分比,已用空间相对于总空间的比例
- Mounted on : 文件系统被挂载到的目录
4. file 指令
$ sudo file -sL |
5. lsblk 指令
$ lsblk -f |
6. blkid 指令
此指令用于查看 块设备 的属性
$ blkid |
二、文件系统的发展
2.1 本地文件系统
文件系统最初是本地操作系统用于管理存储设备的一种方式。早期的需求主要集中在本地文件管理上,例如 Ext4、XFS、FAT32 和 Btrfs 等文件系统,它们用于格式化和使用本地磁盘。在 Linux 系统中,可以通过执行 cat /proc/filesystems 命令来查看系统支持的文件系统列表。
以下是一些常见文件系统的特点,其中包括了一些特殊的文件系统,这些文件系统并非用于常规的数据存储,而是具有特殊用途:
文件系统 | 优点 | 缺点 | 使用场景 | 最大文件大小 |
---|---|---|---|---|
sysfs | - 访问硬件设备信息 - 动态更新 |
- 性能可能受大量设备的影响 | 设备树和硬件配置信息 | N/A |
tmpfs | - 完全基于内存 - 快速读写 - 可限制大小 |
- 数据非持久化 | 临时文件、缓存 | 受限于内存大小 |
bdev | - 用于块设备的管理 | - 较低层,用户通常不直接交互 | 内核中的块设备管理 | N/A |
proc | - 动态显示进程和系统信息 | - 只读 | 进程状态查看和调试 | N/A |
cgroup | - 控制进程资源使用 - 灵活的分组机制 |
- 已被 cgroup2 替代 | 资源管理和隔离 | N/A |
cgroup2 | - 统一的 cgroup 实现 - 更好的资源管理和控制 |
- 兼容性问题 | 资源管理和隔离 | N/A |
cpuset | - 控制进程使用的 CPU 和内存节点 | - 仅限于 CPU 和内存控制 | 进程调度控制 | N/A |
devtmpfs | - 自动创建设备节点 | - 不适合持久化的设备文件 | 设备文件自动管理 | N/A |
configfs | - 管理内核模块配置 | - 较少直接用户交互 | 内核模块配置 | N/A |
debugfs | - 提供调试信息 | - 主要用于开发者 | 内核调试 | N/A |
tracefs | - 收集跟踪数据 | - 主要用于开发者 | 内核跟踪 | N/A |
securityfs | - 提供安全策略信息 | - 较少直接用户交互 | 安全策略管理 | N/A |
sockfs | - 管理套接字文件 | - 较少直接用户交互 | 套接字文件管理 | N/A |
bpf | - 高性能的数据包过滤 | - 复杂性 | 数据包过滤和性能监控 | N/A |
pipefs | - 管理匿名管道 | - 限于进程间通信 | 进程间通信 | N/A |
ramfs | - 完全基于内存 - 快速读写 |
- 数据非持久化 | 快速存储需求 | 受限于内存大小 |
hugetlbfs | - 支持大页分配 - 减少 TLB 缺失 |
- 需要正确配置 | 高性能计算 | 受限于内存大小 |
devpts | - 管理伪终端设备 | - 限于伪终端 | 伪终端设备管理 | N/A |
ext3 | - 成熟稳定 - 支持日志功能 |
- 性能不如新型文件系统 | 通用存储 | 2 TB (早期版本) 16 TB (后期版本) |
ext2 | - 简单高效 | - 无日志功能 | 旧式存储 | 2 TB |
ext4 | - 支持更大的文件和卷 - 高性能 |
- 可能有兼容性问题 | 高性能存储 | 16 TB |
squashfs | - 压缩的只读文件系统 | - 只读 | 固件和映像文件 | 无限制 |
vfat | - 跨平台兼容性好 | - 性能一般 | 闪存盘和移动存储 | 4 GB (标准) |
ecryptfs | - 提供加密功能 | - 性能影响 | 加密文件存储 | 无限制 |
fuseblk | - 用户空间文件系统 - 灵活性高 |
- 安全性和性能问题 | 用户自定义文件系统 | 依具体实现而定 |
fuse | - 用户空间文件系统 - 灵活性高 |
- 安全性和性能问题 | 用户自定义文件系统 | 依具体实现而定 |
fusectl | - 控制 FUSE 实例 | - 较少直接用户交互 | FUSE 管理 | N/A |
efivarfs | - 存储 UEFI 变量 | - 限于 UEFI 变量 | UEFI 变量管理 | 无限制 |
mqueue | - 管理 POSIX 消息队列 | - 限于消息队列 | 进程间消息传递 | N/A |
pstore | - 存储崩溃时的信息 | - 用于故障诊断 | 系统故障诊断 | N/A |
autofs | - 自动挂载文件系统 | - 配置复杂 | 自动挂载 | 依具体实现而定 |
binfmt_misc | - 执行特殊格式的二进制文件 | - 限于特殊格式 | 执行特殊格式文件 | N/A |
这里要提及一下 fuse 文件系统,Fuse(filesystem in userspace),是一个用户空间的文件系统。通过fuse内核模块的支持,开发者只需要根据 fuse 提供的接口实现具体的文件操作就可以实现一个文件系统。由于其主要实现代码位于用户空间中,而不需要重新编译内核,这给开发者带来了众多便利。Google 在Android 11上,为了实现 scoped storage,也引入了fuse 。
2.2 网络文件系统
随着传输技术的发展,人们开始有了新的需求,不止限于本地文件的传输I/O技术,人们也开始对远程数据传输有了需求,人们希望通过 TCP/IP 方式获取数据,就相当于增加了一种可以远距离传输的 I/O 技术,这就引入了网络文件系统的概念。网络文件系统(NFS,Network File System)是一种将远程主机上的分区(目录)经网络挂载到本地系统的一种机制,通过对网络文件系统的支持,用户可以在本地系统上像操作本地分区一样来对远程主机的共享分区(目录)进行操作。目前主流的接入协议有 NFS 协议为代表的 Linux 阵营和以 CIFS/SMB 协议为代表的 Windows 产品阵营。不过随着技术的发展,基本上可以通用了。
2.3 分布式文件系统
支持远程访问的文件系统解决了资源共享的问题,但是这些文件系统虽然能够支持多个客户端访问,但是毕竟是单机,处理能力有限,在大规模的数据访问领域中,例如电商网站,大数据处理,采用 NFS 这种访问方式就无法满足需求。于是,为了可以让多台机器上的多用户通过网络分享文件和存储空间,这就出现了分布式文件系统,该文件系统的服务端通过一个集群来实现,客户端可以并发的访问该集群的多达数万个节点,因此承载能力得到极大的提升。
本地文件系统、网络文件系统和分布式分拣系统这几种文件系统没有本质的差别。只是网络连接的可靠性复杂性等因素,相对于本地总线而言,分布式文件系统接入的存储设备,需要应用层做更多复杂的策略来配合达到相同的效果。随着数字化转型的深入,海量数据对存储系统提出了新的要求,市场上出现了多种分布式存文件系统。如 HDFS、Ceph、GFS、GPFS、Swift 等
三、磁盘结构
我们先来看一下磁盘的物理结构图:
左图为我们常见的物理磁盘的样式,右图为抽象的结构图,对其中标注的术语作如下解释:
- 盘片:硬盘有多个盘片,每盘片有2面(正反两面)
- 磁头:每面一个磁头,并不是只有一个磁头,磁头也不会碰到盘面,磁头等于盘片数量
- 扇区:盘片被分为多个扇形区域,每个扇区存放 512 字节的数据(扇区越多容量越大)
- 磁道:同一盘片不同半径的同心圆
- 柱面:不同盘片相同半径构成的圆(柱面和磁道数量相同)
这里我们需要明白的是磁盘的读写速度就取决于盘面旋转的速度和磁头的旋转(跨越磁道)的速度。这就叫做磁盘的读写延迟。
所有衡量一个硬盘的指标就包括它的“平均寻道时间“,那么盘片的转速越快,那么硬盘的性能越好。笔记本的硬盘一般都是5400转每分钟(RPM),台式机硬盘一般都是7200转/分钟。工业基本的硬盘比如:SCSI有10000转/分钟(即10k转),15k的转速。所以硬盘的转速越快,性能越好,但同时磁盘的发热量就越大。
对于5400转/分钟的转速已经相当快了,如果磁盘直接在空气中旋转,一定会烧起来。所以在硬盘内部是真空的,也不能有任何灰层,应为我们知道磁头距离盘面的距离只有几微米,所以一粒灰层在上面绝对相当于一座山。所以要是你拆开了硬盘核心部件然后再合上运行,绝对一股白烟硬盘就没了。当然把里面做成真空主要是避免灰层
3.1 磁盘容量
- 硬盘存储容量 = 磁头数 × 磁道(柱面)数 × 磁道扇区数 × 每扇区字节数
- 1柱面 = 512 * 扇区数 / (磁头数 × 磁道) = 51263255 = 7.84M
- 可以用柱面/磁头/扇区来唯一定位磁盘上每一个区域
3.2 相关概念
1. 分区
分区 是将物理硬盘划分为多个独立区域的过程,每个区域可以单独使用文件系统进行管理。这些独立区域称为分区。磁盘分区的主要目的是为了更好地组织和管理数据,提高系统性能,以及在多操作系统共存时提供隔离,如 Windows 系统下的 C盘、D盘等
# 显示所有块设备及其挂载点 |
2. 驱动器
磁盘上有未分配的空间,它可以变成一个或多个分区。在原始状态下,一个分区有时被称为一个卷。一旦格式化,它现在可以被称为驱动器,这就是为什么我们在Windows 操作系统内有驱动器字样。
3.2 MBR
Master Boot Record (MBR) 翻译为: 主引导记录,是磁盘引导扇区的一部分,它位于整个磁盘的第0盘面0磁道第0扇区,通常是 512 字节大小。这512个字节不属于任何操作系统,即(你在磁盘上安装操作系统后你的系统也无法正常访问这512个字节),MBR是属于磁盘的,是全局的,是独立在操作系统之外的,MBR 包含了重要的信息,用于引导操作系统和管理磁盘分区。以下是 MBR 的组成部分及其功能:
- 引导代码 (Boot Code)
占据 MBR 的前 446 字节。
包含了引导加载程序的代码,负责检测活动分区并将控制权传递给相应的操作系统引导加载程序。 - 分区表 (Partition Table)
占据 MBR 的接下来的 64 字节(4 个条目,每个条目 16 字节)。
每个条目描述了一个分区的信息,包括起始扇区位置、结束扇区位置、分区类型标识符等。 - 引导签名 (Boot Signature)
最后两个字节是 MBR 的引导签名,通常是 0xAA55。
这个签名用于确认 MBR 是否已被正确写入。
MBR 分区表的限制
- 分区数量限制: MBR 只能支持最多 4 个主分区,或者 3 个主分区加上 1 个扩展分区。扩展分区可以再细分为多个逻辑分区。
- 分区大小限制: MBR 支持的最大分区大小为 2 TiB(2^40 字节)。
四、虚拟文件系统
文件系统的种类众多,而操作系统希望对用户提供一个统一的接口,于是在用户层与文件系统层引入了中间层,这个中间层就称为虚拟文件系统(Virtual File System,VFS)。VFS 定义了一组所有文件系统都支持的数据结构和标准接口,这样程序员不需要了解文件系统的工作原理,只需要了解 VFS 提供的统一接口即可。在 Linux 文件系统中,用户空间、系统调用、虚拟机文件系统、缓存、文件系统以及存储之间的关系如下图:
Linux 支持的文件系统也不少,根据存储位置的不同,可以把文件系统分为三类:
- 磁盘的文件系统,它是直接把数据存储在磁盘中,比如 Ext 2/3/4、XFS 等都是这类文件系统。
- 内存的文件系统,这类文件系统的数据不是存储在硬盘的,而是占用内存空间,我们经常用到的 /proc 和 /sys 文件系统都属于这一类,读写这类文件,实际上是读写内核中相关的数据数据。
- 网络的文件系统,用来访问其他计算机主机数据的文件系统,比如 NFS、SMB 等等。
文件系统首先要先挂载到某个目录才可以正常使用,比如 Linux 系统在启动时,会把文件系统挂载到根目录