页高速缓存和页回写

1. 页高速缓存

页高速缓存(cache)是Linux内核实现的一种主要磁盘缓存。它主要用来减少对磁盘的I/O操作。具体的讲,就是通过把磁盘中的数据缓存到物理内存中,把对磁盘的访问变为对物理内存的访问。

磁盘高速缓存的原因在于:一是访问磁盘的速度要远远低于访问内存的速度;第二,数据一旦被访问,就可能在短期内再次被访问到。

页高速缓存是由RAM中的物理页组成的,缓存中每一页都对应着磁盘中的多个块。当内核开始执行一个页I/O操作时,先检查需要的数据是否在告诉缓存中,如果在,内核就可以直接使用高速缓存中的数据,从而避免访问磁盘。也可以通过块I/O缓冲区把独立的磁盘块与页高速缓存联系在一起,一个缓冲就是一个单独物理磁盘块在内存中的表示,缓冲就是内存到磁盘块的映射描述符,因此通过缓存磁盘块以及缓存块I/O操作。所以,这种缓存也是页高速缓存的一部分。

块I/O操作每次操作一个单独的磁盘块,比如读写索引节点就是一个典型的块I/O操作。内核提供bread底层函数从磁盘读单个块,通过缓冲,这些磁盘块被映射到内存中相应的页面上,这样就被缓存到页高速缓存里了。

 

2. address_space对象

一个物理页可能由多个不连续的物理磁盘块组成。Linux页高速缓存的目标是缓存任何基于页的对象,这包含各种类型的文件和各种类型的内存映射。为了满足普遍性要求,Linux高速缓存使用address_space结构体描述页高速缓存中的页面,该结构定义在<linux/fs.h>中。

address_space结构体的a_ops域指向地址空间对象中的操作函数表,这与VFS对象及其操作表关系类似,操作函数表定义在<linux/fs.h>中,由address_space_operations结构体表示。

 

3. 基树

页高速缓存通过两个参数(一个address_sapce对象和一个偏移量)进行搜索。每个address_space对象都有唯一的基树(radix tree),它保存在page_tree结构体中。基树是一个二叉树,只要指定了文件偏移量,就可以在基树中迅速检索到希望的数据。页高速缓存的搜索函数find_get_page要用函数radix_tree_lookup,该函数会在指定基树中搜索指定页面。

基树核心代码的通用形式在文件lib/radix-tree.c中找到。头文件<linux/radix_treee.h>。

 

4. 缓冲区高速缓存

在2.2版本的内核中,存在两个独立的磁盘缓存:页高速缓存和缓冲区高速缓存。前者缓存页,后者缓存缓冲。但是从2.4版本的内核开始,统一了这两种缓存,现在只有唯一的磁盘缓存--页高速缓存。

虽然如此,内核仍然需要在内存在使用缓冲来表示磁盘块,幸好,缓冲是用页映射块的,所以它正好在页高速缓存中。

 

5. pdflush后台例程

在内存中积累起来的胀页最终必须写回磁盘,在以下两种情况发生时,胀页被写回磁盘:

1) 当空闲内存低于一个特定的阀值时,内核必须将胀页写回磁盘,以便释放内存。

2) 当胀页在内存中驻留时间超过一个特定的阀值时,内核必须将超时的胀页写回磁盘,以确保胀页不会无限制地驻留内存中。

在2.6内核中,由一群内核线程--pdflush后台回写例程--统一执行两种上述工作。

首先,pdflush线程在系统中的空闲低于一个特定的阀值时,将胀页刷新回磁盘。特定的内存阀值可以通过dirty_background_radtio sysctl系统调用设置。当空闲内存低于阀值时:内核便会调用函数wakeup_bdflush唤醒一个pdflush线程,随后pdflush线程会调用函数background_writeout开始将胀页写回磁盘。函数background_writeout会连续地写出数据,直到已经有指定的最小数目的页被写出到磁盘或空闲内存数已经回升并超过阀值或者没有胀页可写的了。

其次,pdflush后台例程会被周期性唤醒,将那些在内存驻留时间过长的胀页写出,确保系统发生故障数据丢失。在系统启动时,内核初始化一个定时器,让它周期地唤醒pdflush线程,随后使其运行函数wb_kupdate。该函数将把所有驻留时间超过百分之dirty_expire_centisecs秒的胀页写回。然后,定时器将再次被初始化百分之dirty_expire_centisecs秒后唤醒pdflush线程。

系统管理员可以在/proc/sys/vm中设置回写相关的参数,也可以通过sysctl系统调用设置他们。

 

5.1. 膝上型电脑模式

膝上型电脑模式是一种特殊的页回写策略,该策略主要意图是将硬盘转动的机械行为最小化,允许硬盘尽可能长时间的停止,以此延长电池供电时间。该模式可通过/proc/sys/vm/laptop_mode文件配置,通常上述配置文件内容为零,如果要开启膝上型电脑模式,则向配置文件中写入1。

 

5.2. bdflush和kuodated

在2.6版本以前,pdflush线程的工作是分别由bdflush和kupdatd两个线程共同完成。

bdflush和pdflush之间的主要区别:一是系统中只有一个bdflush后台线程,而pdflush却可以动态变化;二是bdflush线程基于缓冲,pdflush基于页面,将整个胀页写回磁盘。

 

5.3. 避免拥塞的方法:使用多线程

bdflush仅仅包含一个线程,因此可能在页回写任务重时,造成阻塞。

2.6内核通过使用多个线程pdflush来解决这个问题。每个线程可以相互独立地将胀页刷新回磁盘,而且不同的pdflush线程处理不同的设备队列。另一个优势就是pdflush数量主要取决于页回写的数量和拥塞情况,动态调整。

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值