pdflush进程详解

以下转自:http://blog.csdn.net/kofshower/article/details/7357968

大家知道,在linux操作系统中,写操作是异步的,即写操作返回的时候数据并没有真正写到磁盘上,

而是先写到了系统cache里,随后由pdflush内核线程将系统中的脏页写到磁盘上,在下面几种情况下,
系统会唤醒pdflush回写脏页:

1 、定时方式:
     定时机制定时唤醒pdflush内核线程,周期为/proc/sys/vm/dirty_writeback_centisecs ,单位
是(1/100)秒,每次周期性唤醒的pdflush线程并不是回写所有的脏页,而是只回写变脏时间超过
/proc/sys/vm/dirty_expire_centisecs(单位也是1/100秒)。
注意:变脏的时间是以文件的inode节点变脏的时间为基准的,也就是说如果某个inode节点是10秒前变脏的,
pdflush就认为这个inode对应的所有脏页的变脏时间都是10秒前,即使可能部分页面真正变脏的时间不到10秒,
细节可以查看内核函数wb_kupdate()。

2、 内存不足的时候:
    这时并不将所有的dirty页写到磁盘,而是每次写大概1024个页面,直到空闲页面满足需求为止。

3 、写操作时发现脏页超过一定比例:
    当脏页占系统内存的比例超过/proc/sys/vm/dirty_background_ratio 的时候,write系统调用会唤醒
pdflush回写dirty page,直到脏页比例低于/proc/sys/vm/dirty_background_ratio,但write系统调
用不会被阻塞,立即返回。当脏页占系统内存的比例超过/proc/sys/vm/dirty_ratio的时候, write系
统调用会被被阻塞,主动回写dirty page,直到脏页比例低于/proc/sys/vm/dirty_ratio,这一点在
2.4内核中是没有的。

4 、用户调用sync系统调用:
    这是系统会唤醒pdflush直到所有的脏页都已经写到磁盘为止。


以下转自:http://blog.csdn.net/fireroll/article/details/19155657

一、简介 
由于页高速缓存的缓存作用,写操作实际上会被延迟。
当页高速缓存中的数据比后台存储的数据更新时,那么该数据就被称做脏数据。
在内存中累积起来的脏页最终必须被写回磁盘。

在以下两种情况发生时,脏页被写回磁盘:
.  当空闲内存低于一个特定的阈值时,内核必须将脏页写回磁盘,以便释放内存。 
.  当脏页在内存中驻留时间超过一个特定的阈值时,内核必须将超时的脏页写回磁盘,
   以确保脏页不会无限期地驻留在内存中。
 
上面两种工作的目的完全不同。
实际上,在老内核中,这是由两个独立的内核线程分别完成的。
但是在2.6内核中,由一群内核线程—pdflush后台回写例程—统一执行两种工作。
 
我们来看看这两个目标是如何具体实现的。
首先,当系统中的空闲内存低于一个特定的阈值时,pdflush线程将脏页刷新回磁盘。
该后台回写例程的目的在于在可用物理内存过低时,释放脏页以重新获得内存。
特定的内存阈值可以通过dirty_background_ratio参数设置。
当空闲内存比阈值dirty_ background_ratio还低时,内核便会调用函数wakeup_bdflush()唤醒一个pdflush线程,
随后pdflush线程进一步调用函数background_writeout()开始将脏页写回磁盘。
函数background_ writeout()需要一个长整型参数,该参数指定试图回写的页面数目。

函数background_writeout()会连续地写出数据,直到满足以下两个条件:
.  已经有指定的最小数目的页被写出到磁盘。 
.  空闲内存数已经回升,超过了阈值dirty_background_ratio。

上述条件确保了pdflush操作可以减轻系统中内存不足的压力。
回写操作不会在达到这两个条件前停止,除非pdflush写回了所有的脏页,没有剩下的脏页可再被写回了。
 
要满足第二个目标,pdflush后台例程会被周期性唤醒(和空闲内存是否过低无关),
将那些在内存中驻留时间过长的脏页写出,确保内存中不会有长期存在的脏页。
加入系统发生崩溃,则内存会处于混乱之中,而那些在内存中还没来得及写回磁盘的脏页就会丢失,
所以周期性同步回写非常重要。

在系统启动时,内核初始化一个定时器,让它周期地唤醒pdflush线程,随后使其运行函数wb_kupdate()。
该函数将把所有驻留时间超过百分之dirty_expire_centisecs秒的脏页写回。
然后定时器将再次被初始化为百分之dirty_expire_ centisecs秒后唤醒pdflush线程。
总而言之,pdflush线程周期地被唤醒并且把超过特定期限的脏页写回磁盘。 
 
二、proc下的相关控制参数
系统管理员可以在/proc/sys/vm中设置回写相关的参数,也可以通过sysctl系统调用设置它们。

1. /proc/sys/vm/dirty_ratio
这个参数控制一个进程在文件系统中的文件系统写缓冲区的大小,单位是百分比,表示系统内存的百分比,
表示当一个进程中写缓冲使用到系统内存多少的时候,再有磁盘写操作时开始向磁盘写出数据。
增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。
但是,当你需要持续、恒定的写入场合时,应该降低其数值.
一般缺省是 40。
设置方法如下:
echo 30 >/proc/sys/vm/dirty_ratio
 
2. /proc/sys/vm/dirty_background_ratio
这个参数控制文件系统的pdflush进程,在何时刷新磁盘。单位是百分比,表示系统总内存的百分比,
意思是当磁盘的脏数据缓冲到系统内存多少的时候,pdflush开始把脏数据刷新到磁盘。
增大会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。
但是,当你需要持续、恒定的写入场合时,应该降低其数值.
一般缺省是10。
设置方法如下:
echo 8 >/proc/sys/vm/dirty_background_ratio
 
3. /proc/sys/vm/dirty_writeback_centisecs
Pdflush写后台进程每隔多久被唤醒并执行把脏数据写出到硬盘。单位是 1/100 秒。
如果你的系统是持续地写入动作,那么实际上还是降低这个数值比较好,这样可以把尖峰的写操作削平成多次写操作。
缺省数值是500,也就是 5 秒。
设置方法如下:
# echo 200 >/proc/sys/vm/dirty_writeback_centisecs

4. /proc/sys/vm/dirty_expire_centisecs
这个参数声明Linux内核写缓冲区里面的脏数据多“旧”了之后,pdflush 进程就开始考虑写到磁盘中去。
单位是 1/100秒。
对于特别重载的写操作来说,这个值适当缩小也是好的,但也不能缩小太多,因为缩小太多也会导致IO提高太快。
缺省是 30000,也就是 30 秒的数据就算旧了,将会刷新磁盘。
建议设置为 1500,也就是15秒算旧。
设置方法如下:
echo 1500 >/proc/sys/vm/dirty_expire_centisecs
  
三、内核参数修改后的生效
Linux在系统运行时修改内核参数(/proc/sys与/etc/sysctl.conf),而不需要重新引导系统,
这个功能是通过/proc虚拟文件系统实现的。

在/proc/sys目录下存放着大多数的内核参数,并且设计成可以在系统运行的同时进行更改, 
可以通过更改/proc/sys中内核参数对应的文件达到修改内核参数的目的(修改过后,保存配置文件就马上自动生效),
不过重新启动机器后之前修改的参数值会失效,所以只能是一种临时参数变更方案。
(适合调试内核参数优化值的时候使用,如果设置值有问题,重启服务器还原原来的设置参数值了。简单方便。)

但是如果调试内核参数优化值结束后,需要永久保存参数值,
就要通过修改/etc/sysctl.conf内的内核参数来永久保存更改。
但只是修改sysctl文件内的参数值,确认保存修改文件后,设定的参数值并不会马上生效,
如果想使参数值修改马上生效,并且不重启服务器,可以执行下面的命令:
  # sysctl –p

下面介绍一下/proc/sys下内核文件与配置文件sysctl.conf中变量的对应关系:
由于可以修改的内核参数都在/proc/sys目录下,所以sysctl.conf的变量名省略了目录的前面部分(/proc/sys)。
即将/proc/sys中的文件转换成sysctl中的变量依据下面两个简单的规则:
1.去掉前面部分/proc/sys
2.将文件名中的斜杠变为点

这两条规则可以将/proc/sys中的任一文件名转换成sysctl中的变量名。
例如:
/proc/sys/net/ipv4/ip_forward =》 net.ipv4.ip_forward
/proc/sys/kernel/hostname =》 kernel.hostname

可以使用下面命令查询所有可修改的变量名
  # sysctl –a

你可能感兴趣的:(pdflush进程详解)