linux内核页高速缓存,Linux页高速缓存和页回写

页高速缓存(cache)是Linux内核实现磁盘缓存的机制。磁盘高速缓存之所以重要的原因有二:1.访问磁盘的速度要远远低于访问内存的速度;2.数据一旦被访问,根据临时局部原理,它将很有可能在短时间内再次被访问到。

1.缓存手段

页高速缓存是由内存中的物理页面组成的,其内容对应磁盘上的物理块。页高速缓存大小能动态调整--它可以通过占用空闲内存以扩张大小,也可以自我收缩以缓解内存压力。注意,系统不一定要将整个文件都缓存,而只是缓存部分。

1.1写缓存

包括以下三种:

不缓存。直接写磁盘。

写透缓存。写操作自动更新内存缓存,同时也更新磁盘文件。

回写。程序执行写操作直接写到缓存中,后端存储不会立刻更新,而是将页高速缓存中被写入的页面标记为『脏』页,并被加入到脏页链表。然后由一个进程周期性将脏页链表中的页写回到磁盘。

1.2缓存回收

缓存算法最后涉及的重要内容是缓存中的数据如何清除;或者是为更重要的缓存项腾出位置;或者是收缩缓存大小,腾出内存给其他地方使用。这个工作被称为缓存回收策略。Linux的缓存回收是通过选择干净页进行简单替换。如果缓存中没有足够干净页面,内核将强制进行回写操作,以腾出更多地干净可用页。理想的回收策略是回收那些以后最不可能使用的页面,但这个谁也不知道,所以理想的回收策略被称为预测算法。

目前有的算法如:1.最近最少使用算法(LRU)。2.双链策略。这个是Linux实现的一个修改过的LRU算法。它维护两个链表:活动链表和非活动链表,处于活动链表上的页面被认为是『热』的且不会被换出,而非活动链表页面可以被换出。具体算法参考详细资料。

2.Linux页高速缓存

页高速缓存缓存的是内存页面。在页高速缓存中的页可能包含了多个不连续的物理磁盘块。比如x86体系下一个屋里页大小是4KB。而大多数文件系统的块大小仅仅是512B。所以8个块才填满一个页面。另外因为文件本身可能分布在磁盘的各个位置,所以页面中映射的快也不需要连续。

虽然Linux页高速缓存可以通过扩展inode结构体支持页I/O操作,但这样会将页高速缓存局限于文件,Linux页高速缓存使用了一个新对象管理缓存项也页I/O操作,这个对象是address_space结构体。该结构体是vm_area_struct的物理地址对等体。当一个文件可以被10个vm_area_struct结构体标识,那么这个文件只能有一个address_space数据结构--也就是文件可以有多个虚拟地址,但是只能在物理内存有一份。

8e60267cb7f862b83f3e5069bc432acc.png

其中i_mmap字段是一个优先搜索树,它的搜索范围包含了在address_space中所有共享的与私有的映射页面。优先搜索树是一种巧妙地将堆与radix树结合的快速检索树。

如果搜索的页并没在高速缓存中,find_get_page()会返回一个NULL,并且内核将分配一个新页面,然后将之前搜索的页加入到页高速缓存中。

通常写操作包括:在页高速缓存中搜索需要的页,如果需要的页不在其中,那么内核在高速缓存中新分配一空闲项;下一步,内核创建一个写请求;接着数据被从用户控件拷贝到了内核缓冲;最后将数据写入磁盘。

3.缓冲区高速缓存

独立的磁盘块通过块I/O缓冲也要被存入页高速缓存。一个缓冲室一个物理磁盘块在内存里地表示。缓冲的作用就是映射内存中的页面到磁盘块,这样一来页高速缓存在块I/O操作时也减少了磁盘访问,因为它缓存磁盘块和减少I/O操作。这个缓存通常被称为缓冲区高速缓存,虽然实现上它没有座位独立缓存,而是作为页高速缓存的一部分。块I/O操作又一次操作一个单独的磁盘块(扇区)。普通的块I/O操作是读写i节点。通过缓存,磁盘块映射到它们相关的内存页,并缓存到页高速缓存中。在2.4以及之后的版本,将他们统一了。

在以下3种情况发生时,脏页需要被回写到磁盘:

当空闲内存低于一个特定的阈值。

当脏页在内存中驻留时间超过一个特定的阈值。

当用户进程调用sync()和fsync()。

一组flusher线程干的就是这三个工作,它将会被周期性唤醒(和空闲内存是否过低无关)进行回写。

参考

《Linux内核设计与实现》

说明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值