文章详情页 您现在的位置是:网站首页>文章详情

Linux文件系统的工作原理

图片丢失 Jeeyshe 发表于:2020年4月20日 22:44 分类:【操作系统 485次阅读

Linux中一切皆文件

在linux操作系统中,我们最常见的文本,图片,可执行二进制文件这些是最为常见的文件。除此之外文件夹也是一种特殊的文件,软链接、硬链接依然是文件。不仅如此,就连我们/dev下面的硬件设备、套接字、管道这些东西在Linux中统统都是文件。

索引节点和目录项

Linux中所有文件都有一个唯一与之对应的索引节点(Index Node),索引节点记录了文件的元数据,操作系统并不通过文件名,而是通过索引节点来管理文件,用目录项(Directory Entry)来描述文件之间的关系。

  • 索引节点,简称为 inode,用来记录文件的元数据,比如 inode 编号、文件大小、访问权限、修改日期、数据的位置等。索引节点和文件一一对应,它跟文件内容一样,都会被持久化存储到磁盘中。所以记住,索引节点同样占用磁盘空间。

  • 目录项,简称为 dentry,用来记录文件的名字、索引节点指针以及与其他目录项的关联关系。多个关联的目录项,就构成了文件系统的目录结构。不过,不同于索引节点,目录项是由内核维护的一个内存数据结构,所以通常也被叫做目录项缓存。

简言之,索引节点相当于文件的指针,目录项维护着文件的树型关系。

磁盘的存储区域

  • 扇区:磁盘最小读写单位为扇区,每个扇区大小为512B

  • 逻辑块:如果操作系统以最小单位读写磁盘,效率无疑是非常底下的,因此将8个连续扇区组成一个4k大小的逻辑块作为数据单元来进行管理

在进行文件系统格式化时,会将磁盘划分为三个区域:

  • 超级块,存储整个文件系统的状态。

  • 索引节点区,用来存储索引节点。

  • 数据块区,则用来存储文件数据。

磁盘、索引节点、目录项、逻辑块的关系如下图所示:

disk-blok-inode-dentry.png

目录项本身是一个内存缓存,索引节点则是存储在磁盘中,但是为了加快文件访问速度,索引节点和文件内容也会被读入到缓存中。

虚拟文件系统

索引节点、目录项、逻辑块、超级块是构成文件系统的四大基本要素。但是,为了能够使用各种不同的文件系统,在用户进程和内核之间引入了一个抽象层——虚拟文件系统VFS。

Linux-File-System.png

VFS定义了一组所有文件系统都支持的数据结构和标准接口。因此用户进程只需要和VFS交互即可,无需针对每一种文件系统开发不同的应用程序。

文件系统按照存储位置不同,可分为三类:

  • 基于磁盘的文件系统:Ext4、XFS、OverlayFS 等, 直接将数据存储在本地挂在的磁盘。

  • 基于内存的文件系统:如/proc、/sys等目录,无需分配磁盘空间,但是占用内存。

  • 网络文件系统:访问远程其他主机的文件系统,如NTFS、SMB等。

文件系统的IO类型

根据文件系统的读写差异,可以将IO分为四种类型:

  • 缓冲 I/O,是指利用标准库缓存来加速文件的访问,而标准库内部再通过系统调度访问文件。

  • 非缓冲 I/O,是指直接通过系统调用来访问文件,不再经过标准库缓存。

此处标准库缓存指的是利用栈、队列等一些数据结构进行的资源调度,而不是页缓存。无论是否缓冲IO,都会通过系统调用页缓存来减少IO次数。
根据是否利用操作系统的页缓存,可以把文件 I/O 分为直接 I/O 与非直接 I/O。

  • 直接 I/O,是指跳过操作系统的页缓存,直接跟文件系统交互来访问文件。

  • 非直接 I/O 正好相反,文件读写时,先要经过系统的页缓存,然后再由内核或额外的系统调用,真正写入磁盘。

通常情况下我们的IO都是非直接IO,在数据库等场景中,你还会看到,跳过文件系统读写磁盘的情况,也就是我们通常所说的裸 I/O

据应用程序是否阻塞自身运行,可以把文件 I/O 分为阻塞 I/O 和非阻塞 I/O:

  • 所谓阻塞 I/O,是指应用程序执行 I/O 操作后,如果没有获得响应,就会阻塞当前线程,自然就不能执行其他任务。

  • 所谓非阻塞 I/O,是指应用程序执行 I/O 操作后,不会阻塞当前的线程,可以继续执行其他的任务,随后再通过轮询或者事件通知的形式,获取调用的结果。

默认情况下IO都是阻塞的。网络编程中非阻塞 I/O,通常会跟 select/poll 配合,用在网络套接字的 I/O 中。

根据是否等待响应结果,可以把文件 I/O 分为同步和异步 I/O:

  • 所谓同步 I/O,是指应用程序执行 I/O 操作后,要一直等到整个 I/O 完成后,才能获得 I/O 响应。

  • 所谓异步 I/O,是指应用程序执行 I/O 操作后,不用等待完成和完成后的响应,而是继续执行就可以。等到这次 I/O 完成后,响应会用事件通知的方式,告诉应用程序。

文件系统的观测

  • 容量

jeeyshe@jeeyshe-PC:~$ df
文件系统           1K-块     已用     可用 已用% 挂载点
udev             3997588        0  3997588    0% /dev
tmpfs             805208     1868   803340    1% /run
/dev/sda3       46631732  8521096 35712124   20% /
tmpfs            4026032    44240  3981792    2% /dev/shm
tmpfs               5120        4     5116    1% /run/lock
tmpfs            4026032        0  4026032    0% /sys/fs/cgroup
/dev/sda1         306584     6668   299916    3% /boot/efi
/dev/sda4       93266544  8084300 80401548   10% /home
tmpfs             805204       40   805164    1% /run/user/1000
/dev/sda5       93266544    57368 88428480    1% /media/jeeyshe/_dde_data
/dev/sdb3      115272700 45983312 69289388   40% /media/jeeyshe/500CEF460CEF25A6

索引节点的容量,(也就是 Inode 个数)是在格式化磁盘时设定好的,一般由格式化工具自动生成。当你发现索引节点空间不足,但磁盘空间充足时,很可能就是过多小文件导致的。

加入一下参数可以看到更加详细和人性化的容量信息:

jeeyshe@jeeyshe-PC:~$ df -ih
文件系统       Inode 已用(I) 可用(I) 已用(I)% 挂载点
udev            976K     576    976K       1% /dev
tmpfs           983K     890    983K       1% /run
/dev/sda3       2.9M    239K    2.7M       9% /
tmpfs           983K      46    983K       1% /dev/shm
tmpfs           983K       7    983K       1% /run/lock
tmpfs           983K      17    983K       1% /sys/fs/cgroup
/dev/sda1          0       0       0        - /boot/efi
/dev/sda4       5.7M     98K    5.6M       2% /home
tmpfs           983K      28    983K       1% /run/user/1000
/dev/sda5       5.7M      11    5.7M       1% /media/jeeyshe/_dde_data
/dev/sdb3        67M    503K     67M       1% /media/jeeyshe/500CEF460CEF25A6
  • 缓存:此处只观测索引节点和目录项

slabtop.png

关于页缓存、swap、buf等概念,将在其他篇章介绍。

版权声明 本文属于本站  原创作品,文章版权归本站及作者所有,请尊重作者的创作成果,转载、引用自觉附上本文永久地址: https://www.lujianxin.com/x/art/ogqjbet7znn9

文章评论区

作者名片

图片丢失
  • 作者昵称:Jeeyshe
  • 原创文章:48篇
  • 转载文章:3篇
  • 加入本站:562天

站点信息

  • 运行天数:563天
  • 累计访问:96174人次
  • 今日访问:135人次
  • 原创文章:56篇
  • 转载文章:4篇
  • 微信公众号:第一时间获取更新信息