前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解Linux VFS和Page Cache

深入理解Linux VFS和Page Cache

作者头像
luoxn28
发布2020-04-21 16:20:36
2.9K0
发布2020-04-21 16:20:36
举报
文章被收录于专栏:TopCoderTopCoder

戳蓝字「TopCoder」关注我们哦!

编者注:在分析完 Linux inode 基础概念 之后,让我们看下inode在内存中对应的文件系统抽象VFS,然后分析下关于 磁盘操作 中Page Cache的回写策略。

VFS(虚拟文件系统层)

VFS是虚拟文件系统层(进程与文件系统之间的抽象层),与它相关的数据结构只存在于物理内存当中。其目的是屏蔽下层具体文件系统操作的差异,为上层的操作提供一个统一接口,正是由于VFS的存在,Linux中允许多个不同的文件系统共存。

VFS中包含着向物理文件系统转换的一系列数据结构,如VFS超级块、VFS的Inode、各种操作函数的转换入口等。Linux中VFS依靠四个主要的数据结构来描述其结构信息,分别为超级块、索引结点、目录项和文件对象,这些数据结构大都会与磁盘上的对应上。

  • 超级块(Super Block):超级块对象表示一个文件系统。它存储一个已安装的文件系统的控制信息,包括文件系统名称(比如Ext2)、文件系统的大小和状态、块设备的引用和元数据信息(比如空闲列表等等)。超级块与磁盘上文件系统的超级块对应。
  • 索引结点(Inode):索引结点对象存储了文件的相关元数据信息,例如:文件大小、设备标识符、用户标识符、用户组标识符等等。Inode分为两种:一种是VFS的Inode,一种是具体文件系统的Inode。前者在内存中,后者在磁盘中。所以每次其实是将磁盘中的Inode调进填充内存中的Inode,这样才是算使用了磁盘文件Inode。当创建一个文件的时候,就给文件分配了一个Inode。一个Inode只对应一个实际文件,一个文件也会只有一个Inode(Unix/Linux系统中目录也是一种文件,打开目录实际上就是打开目录文件。目录文件的结构非常简单,就是一系列目录项(dirent)的列表。每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码)。
  • 目录项(Dentry):引入目录项对象的概念主要是出于方便查找文件的目的。不同于前面的两个对象,目录项对象只存在于内存中,实际对应的是磁盘的目录innode对象。VFS在查找的时候,根据一层一层的目录项找到对应的每个目录项的Inode,那么沿着目录项进行操作就可以找到最终的文件。
  • 文件对象(File):文件对象描述的是进程已经打开的文件。因为一个文件可以被多个进程打开,所以一个文件可以存在多个文件对象,但多个文件对象其对应的索引节点和目录项对象肯定是惟一的,关系如下图:

由于进程中File对象有独立的文件偏移量(current file offset),因此多个进程可以读写文件的不同位置的数据,但是一般不建议这样玩,因为系统不保证该情况下的写的原子性,多进程可以通过文件锁实现对文件内容的写保护。

PageCache

Page cache是通过将磁盘中的数据缓存到内存中,从而减少磁盘I/O操作,从而提高性能。此外,还要确保在page cache中的数据更改时能够被同步到磁盘上,后者被称为page回写(page writeback)。一个inode对应一个page cache对象,一个page cache对象包含多个物理page。

当内核发起一个读请求时(例如进程发起read()请求),首先会检查请求的数据是否缓存到了page cache中,如果有,那么直接从内存中读取,不需要访问磁盘,这被称为cache命中(cache hit)。如果cache中没有请求的数据,即cache未命中(cache miss),就必须从磁盘中读取数据。然后内核将读取的数据缓存到cache中,这样后续的读请求就可以命中cache了。page可以只缓存一个文件部分的内容,不需要把整个文件都缓存进来。

当内核发起一个写请求时(例如进程发起write()请求),同样是直接往cache中写入,此时不会立即同步到磁盘,而是将写入的page设置为脏页,并将其加入dirty list中,内核会负责定期同步到磁盘保持二者一执行。

page cache另一个主要工作是回收page释放内存空间,此时会选择合适的page进行释放,如果是脏页会先同步到磁盘然后释放。此时是如何选择cache页的呢?Linux使用的策略是基于LRU改进的Two-List策略:

Two-List策略维护了两个list,active list 和 inactive list。在active list上的page被认为是hot的,不能释放。只有inactive list上的page可以被释放的。首次缓存的数据的page会被加入到inactive list中,已经在inactive list中的page如果再次被访问,就会移入active list中。两个链表都使用了伪LRU算法维护,新的page从尾部加入,移除时从头部移除,就像队列一样。如果active list中page的数量远大于inactive list,那么active list头部的页面会被移入inactive list中,从而位置两个表的平衡。

触发脏页回写到磁盘时机如下:

  • 用户进程调用sync() 和 fsync()系统调用;
  • 空闲内存低于特定的阈值(threshold);
  • Dirty数据在内存中驻留的时间超过一个特定的阈值。

注意这里的page cache的脏页回写机制可以和mmap的脏页回写机制做下对比,mmap会在一定时间后系统自动回写脏页面到磁盘,也就是说mamp中修改过的脏页面并不会立即更新回文件中,而是有一段时间的延迟,可以调用msync()来强制同步, 这样所写的内容就能立即保存到文件里了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 TopCoder 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • VFS(虚拟文件系统层)
  • PageCache
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档