Linux内核文件cache管理机制介绍

简介: 1 操作系统和文件Cache管理 操作系统是计算机上最为重要的软件,他负责管理计算机的各种硬件资源,并将这些物理资源抽象成各种接口供上层应用使用。所以从程序的角度看,操作系统就好比是一个虚拟机,这个虚拟机不提供各种硬件资源的具体细节,而仅仅提供进程、文件、地址空间以及进程间通信等等逻辑概念。 对于存储设备上的数据,操作系统向应用程序提供的逻辑概念就是“文件”。应用程序要存储或访问数据时

1 操作系统和文件Cache管理

操作系统是计算机上最为重要的软件,他负责管理计算机的各种硬件资源,并将这些物理资源抽象成各种接口供上层应用使用。所以从程序的角度看,操作系统就好比是一个虚拟机,这个虚拟机不提供各种硬件资源的具体细节,而仅仅提供进程、文件、地址空间以及进程间通信等等逻辑概念。

对于存储设备上的数据,操作系统向应用程序提供的逻辑概念就是“文件”。应用程序要存储或访问数据时,只需要向这个文件读或者写入内容即可,而文件与物理存储设备的交互则由操作系统提供。

2 文件Cache的地位和作用

文件Cache是文件在数据内存中的副本,因此文件Cache管理与内存管理系统和文件系统相关:一方面文件Cache作为物理内存的一部分,需要参与内存的分配与回收。另一方面,cache中的数据来源于存储设备上的文件,需要通过文件系统与存储设备进行读写交互。

如图1所示,具体的文件系统,比如ext2/ext2,jfs,ntfs等等负责在文件Cache和存储设备之间交换数据,位于文件系统之上的虚拟文件系统VFS负责在应用程序和文件Cache之间通过read和write等接口交换数据。内存管理系统负责内存的分配与回收,同时虚拟内存管理系统(VMM)则允许应用程序和文件Cache之间通过memory map的方式交换数据。


3 文件Cache的相关数据结构

在Linux的实现中,文件Cache分为两个层面,page cache和buffer cache。每一个page cache包含若干个buffer cache。VFS负责page cache和用户空间的数据交换;内存管理系统负责page cache的分配与回收,同时在使用memory map访问时负责建立映射。而具体的文件系统则与buffer cache进行交互,将外围存储设备上的数据和buffer cache之间进行交换。

在Linux内核中,文件的每个数据块最多只能对应一个page cache项,其通过两个数据结构管理,一个radix tree另一个就是双向链表。radix tree是一个搜索树,linux利用这个数据结构来通过文件内偏移快速丁文cache项。下图是radix tree的⼀一个⽰示意图,该radix tree 的分叉为4(22),树⾼高为4,⽤用来快速定位8位⽂文件内偏移。Linux(2.6.7)内核中的分叉为 64(26),树⾼高为6(64位系统)或者11(32位系统),⽤用来快速定位32 位或者64 位偏移,radix tree中的每⼀一个叶⼦子节点指向⽂文件内相应偏移所对应的Cache项。

另⼀一个数据结构是双向链表,Linux内核为每⼀一⽚片物理内存区域(zone)维护active_listinactive_list两个双向链表,这两个list主要⽤用来实现物理内存的回收。这两个链表上除了⽂文件Cache之外,还包括其它匿名(Anonymous)内存,如进程堆栈等。 


4 文件Cache的预读和替换

Linux内核中文件预读算法的具体过程是这样的:对于每个文件的第一个读请求,系统读入所请求的页面并读入紧随其后的少数几个页面(不少于一个页面,通常是三个页面),这时的预读称为同步预读。对于第二次读请求,如果所读页面不在Cache中,即不在前次预读的group中,则表明文件访问不是顺序访问,系统继续采用同步预读;如果所读页面在Cache中,则表明前次预读命中,操作系统把预读group扩大一倍,并让底层文件系统读入group中剩下尚不在Cache中的文件数据块,这时的预读称为异步预读。无论第二次读请求是否命中,系统都要更新当前预读group的大小。此外,系统中定义了一个window,它包括前一次预读的group和本次预读的group。任何接下来的读请求都会处于两种情况之一:第一种情况是所请求的页面处于预读window中,这时继续进行异步预读并更新相应的window和group;第二种情况是所请求的页面处于预读window之外,这时系统就要进行同步预读并重置相应的window和group。图5是Linux内核预读机制的一个示意图,其中a是某次读操作之前的情况,b是读操作所请求页面不在window中的情况,而c是读操作所请求页面在window中的情况。

Linux内核中文件Cache替换的具体过程是这样的:刚刚分配的Cache项链入到inactive_list头部,并将其状态设置为active,当内存不够需要回收Cache时,系统首先从尾部开始反向扫描active_list并将状态不是referenced的项链入到inactive_list的头部,然后系统反向扫描inactive_list,如果所扫描的项的处于合适的状态就回收该项,直到回收了足够数目的Cache项。


5 文件Cache相关API及其实现

Linux内核中与文件Cache操作相关的API有很多,按其使用方式可以分成两类:一类是以拷贝方式操作的相关接口, 如read/write/sendfile等,其中sendfile在2.6系列的内核中已经不再支持;另一类是以地址映射方式操作的相关接口,如mmap等。

第一种类型的API在不同文件的Cache之间或者Cache与应用程序所提供的用户空间buffer之间拷贝数据,其实现原理如图7所示。

第二种类型的API将Cache项映射到用户空间,使得应用程序可以像使用内存指针一样访问文件,Memory map访问Cache的方式在内核中是采用请求页面机制实现的,其工作过程如图8所示。

首先,应用程序调用mmap(图中1),陷入到内核中后调用do_mmap_pgoff(图中2)。该函数从应用程序的地址空间中分配一段区域作为映射的内存地址,并使用一个VMA(vm_area_struct)结构代表该区域,之后就返回到应用程序(图中3)。当应用程序访问mmap所返回的地址指针时(图中4),由于虚实映射尚未建立,会触发缺页中断(图中5)。之后系统会调用缺页中断处理函数(图中6),在缺页中断处理函数中,内核通过相应区域的VMA结构判断出该区域属于文件映射,于是调用具体文件系统的接口读入相应的Page Cache项(图中7、8、9),并填写相应的虚实映射表。经过这些步骤之后,应用程序就可以正常访问相应的内存区域了。



相关文章
|
7天前
|
算法 Linux 调度
深入理解Linux内核调度器:从基础到优化####
本文旨在通过剖析Linux操作系统的心脏——内核调度器,为读者揭开其高效管理CPU资源的神秘面纱。不同于传统的摘要概述,本文将直接以一段精简代码片段作为引子,展示一个简化版的任务调度逻辑,随后逐步深入,详细探讨Linux内核调度器的工作原理、关键数据结构、调度算法演变以及性能调优策略,旨在为开发者与系统管理员提供一份实用的技术指南。 ####
32 4
|
11天前
|
缓存 算法 Linux
深入理解Linux内核调度器:公平性与性能的平衡####
真知灼见 本文将带你深入了解Linux操作系统的核心组件之一——完全公平调度器(CFS),通过剖析其设计原理、工作机制以及在实际系统中的应用效果,揭示它是如何在众多进程间实现资源分配的公平性与高效性的。不同于传统的摘要概述,本文旨在通过直观且富有洞察力的视角,让读者仿佛亲身体验到CFS在复杂系统环境中游刃有余地进行任务调度的过程。 ####
31 6
|
9天前
|
缓存 资源调度 安全
深入探索Linux操作系统的心脏——内核配置与优化####
本文作为一篇技术性深度解析文章,旨在引领读者踏上一场揭秘Linux内核配置与优化的奇妙之旅。不同于传统的摘要概述,本文将以实战为导向,直接跳入核心内容,探讨如何通过精细调整内核参数来提升系统性能、增强安全性及实现资源高效利用。从基础概念到高级技巧,逐步揭示那些隐藏在命令行背后的强大功能,为系统管理员和高级用户打开一扇通往极致性能与定制化体验的大门。 --- ###
32 9
|
8天前
|
缓存 负载均衡 Linux
深入理解Linux内核调度器
本文探讨了Linux操作系统核心组件之一——内核调度器的工作原理和设计哲学。不同于常规的技术文章,本摘要旨在提供一种全新的视角来审视Linux内核的调度机制,通过分析其对系统性能的影响以及在多核处理器环境下的表现,揭示调度器如何平衡公平性和效率。文章进一步讨论了完全公平调度器(CFS)的设计细节,包括它如何处理不同优先级的任务、如何进行负载均衡以及它是如何适应现代多核架构的挑战。此外,本文还简要概述了Linux调度器的未来发展方向,包括对实时任务支持的改进和对异构计算环境的适应性。
28 6
|
9天前
|
缓存 Linux 开发者
Linux内核中的并发控制机制:深入理解与应用####
【10月更文挑战第21天】 本文旨在为读者提供一个全面的指南,探讨Linux操作系统中用于实现多线程和进程间同步的关键技术——并发控制机制。通过剖析互斥锁、自旋锁、读写锁等核心概念及其在实际场景中的应用,本文将帮助开发者更好地理解和运用这些工具来构建高效且稳定的应用程序。 ####
28 5
|
10天前
|
Linux 开发工具 Perl
在Linux中,有一个文件,如何删除包含“www“字样的字符?
在Linux中,如果你想删除一个文件中包含特定字样(如“www”)的所有字符或行,你可以使用多种文本处理工具来实现。以下是一些常见的方法:
36 5
|
9天前
|
算法 Unix Linux
深入理解Linux内核调度器:原理与优化
本文探讨了Linux操作系统的心脏——内核调度器(Scheduler)的工作原理,以及如何通过参数调整和代码优化来提高系统性能。不同于常规摘要仅概述内容,本摘要旨在激发读者对Linux内核调度机制深层次运作的兴趣,并简要介绍文章将覆盖的关键话题,如调度算法、实时性增强及节能策略等。
|
10天前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
29 6
|
10天前
|
存储 监控 安全
Linux内核调优的艺术:从基础到高级###
本文深入探讨了Linux操作系统的心脏——内核的调优方法。文章首先概述了Linux内核的基本结构与工作原理,随后详细阐述了内核调优的重要性及基本原则。通过具体的参数调整示例(如sysctl、/proc/sys目录中的设置),文章展示了如何根据实际应用场景优化系统性能,包括提升CPU利用率、内存管理效率以及I/O性能等关键方面。最后,介绍了一些高级工具和技术,如perf、eBPF和SystemTap,用于更深层次的性能分析和问题定位。本文旨在为系统管理员和高级用户提供实用的内核调优策略,以最大化Linux系统的效率和稳定性。 ###
|
10天前
|
Linux
在 Linux 系统中,`find` 命令是一个强大的文件查找工具
在 Linux 系统中,`find` 命令是一个强大的文件查找工具。本文详细介绍了 `find` 命令的基本语法、常用选项和具体应用示例,帮助用户快速掌握如何根据文件名、类型、大小、修改时间等条件查找文件,并展示了如何结合逻辑运算符、正则表达式和排除特定目录等高级用法。
37 6