找回密码
 注册
关于网站域名变更的通知
查看: 285|回复: 2
打印 上一主题 下一主题

pdflush进程详解

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-4-17 10:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
大家知道,在linux操作系统中,写操作是异步的,即写操作返回的时候数据并没有真正写到磁盘上,( K2 L0 l. m5 M+ M% c9 G" l/ J

9 W) S. N, M% x) i而是先写到了系统cache里,随后由pdflush内核线程将系统中的脏页写到磁盘上,在下面几种情况下,, I. \  U' f2 Y4 [+ U/ \/ s; B
系统会唤醒pdflush回写脏页:
; b; w9 Z: x, e1 n- W4 n$ G0 i5 G1 、定时方式:! O/ K9 [1 Z+ j/ J
     定时机制定时唤醒pdflush内核线程,周期为/proc/sys/vm/dirty_writeback_centisecs ,单位
# X) i: B9 q! G" e6 n6 f是(1/100)秒,每次周期性唤醒的pdflush线程并不是回写所有的脏页,而是只回写变脏时间超过0 ~" D0 [" Y) S$ L, P/ [
/proc/sys/vm/dirty_expire_centisecs(单位也是1/100秒)。) R( [1 Z) @/ q) {: r' Y2 f5 u
注意:变脏的时间是以文件的inode节点变脏的时间为基准的,也就是说如果某个inode节点是10秒前变脏的,
# V  j# I" h; l- J5 G; [pdflush就认为这个inode对应的所有脏页的变脏时间都是10秒前,即使可能部分页面真正变脏的时间不到10秒,
0 A4 C+ M' e6 X/ }8 a  P细节可以查看内核函数wb_kupdate()。
8 p& O4 ]" j  |$ W
/ q/ `7 [3 k+ s! m, X4 ]5 n7 F2、 内存不足的时候:
$ q$ K. f) I( n& f' P    这时并不将所有的dirty页写到磁盘,而是每次写大概1024个页面,直到空闲页面满足需求为止。8 l9 I0 W- M$ @  d
+ N6 U; w4 l8 `0 z% u+ K
3 、写操作时发现脏页超过一定比例:$ B+ ^9 v. c9 i: x* l
    当脏页占系统内存的比例超过/proc/sys/vm/dirty_background_ratio 的时候,write系统调用会唤醒4 @, C3 b+ O! c- a
pdflush回写dirty page,直到脏页比例低于/proc/sys/vm/dirty_background_ratio,但write系统调- U: s/ S+ Y# E( i; f+ C0 x
用不会被阻塞,立即返回。当脏页占系统内存的比例超过/proc/sys/vm/dirty_ratio的时候, write系
  ?  V+ M, l( D6 @$ f统调用会被被阻塞,主动回写dirty page,直到脏页比例低于/proc/sys/vm/dirty_ratio,这一点在: T* F8 G( _4 D5 t2 D2 Z8 E
2.4内核中是没有的。: f: {- d& B& ~0 G2 J1 ~2 G

: t5 e6 r' U% v& E4 l: ^4 、用户调用sync系统调用:
, P1 j4 ~" ], v, h; I, c    这是系统会唤醒pdflush直到所有的脏页都已经写到磁盘为止。7 h: D5 t/ T3 A* J
) E' k& [& H& y4 l% `2 I) F
" z. s) P5 b  P1 f- G2 m
一、简介
" a8 d+ z, B) d& I" S4 `9 [由于页高速缓存的缓存作用,写操作实际上会被延迟。
& T3 N; t# N" _' T( \% {2 u当页高速缓存中的数据比后台存储的数据更新时,那么该数据就被称做脏数据。
: {% _& r" D! k1 P8 y' Y在内存中累积起来的脏页最终必须被写回磁盘。9 I: j' r$ {8 n- u. Q
$ f' j3 o) e  m% i( _
在以下两种情况发生时,脏页被写回磁盘:
7 p3 R3 f; Z& @1 f.  当空闲内存低于一个特定的阈值时,内核必须将脏页写回磁盘,以便释放内存。 : k& {' I* q) g2 O0 {" z% T$ s1 n
.  当脏页在内存中驻留时间超过一个特定的阈值时,内核必须将超时的脏页写回磁盘,
0 P+ a6 w1 y4 Y  Y# D$ @   以确保脏页不会无限期地驻留在内存中。
6 y7 y/ q8 d7 {( B, \* p; c+ B* U
* f) l* }/ t% \3 `% d! d7 S上面两种工作的目的完全不同。' o$ N4 O7 J* k. f
实际上,在老内核中,这是由两个独立的内核线程分别完成的。+ C- [- F) f, Q1 S3 Z; {
但是在2.6内核中,由一群内核线程—pdflush后台回写例程—统一执行两种工作。
# T1 o' S0 W: @8 e, C5 r- u" W3 p& b3 ~$ d+ J+ ?
我们来看看这两个目标是如何具体实现的。
- C; d/ A  d3 O; ^# ^4 }% `首先,当系统中的空闲内存低于一个特定的阈值时,pdflush线程将脏页刷新回磁盘。! B) s/ [1 `5 o3 Z" A1 d
该后台回写例程的目的在于在可用物理内存过低时,释放脏页以重新获得内存。# h' }2 G/ w1 ^8 R/ P
特定的内存阈值可以通过dirty_background_ratio参数设置。
0 Z& a: g  @/ j1 e$ ^当空闲内存比阈值dirty_ background_ratio还低时,内核便会调用函数wakeup_bdflush()唤醒一个pdflush线程,
, ~- q' p, h) J- w随后pdflush线程进一步调用函数background_writeout()开始将脏页写回磁盘。
% I0 M1 W' k7 Q  G; A函数background_ writeout()需要一个长整型参数,该参数指定试图回写的页面数目。# i( ~9 _! c* y7 I- L+ k* c
- _* q6 M& w( u6 Z% y" @- m
函数background_writeout()会连续地写出数据,直到满足以下两个条件:
- P% }  }) T3 V& B.  已经有指定的最小数目的页被写出到磁盘。 ' i: n4 c0 q9 O
.  空闲内存数已经回升,超过了阈值dirty_background_ratio。8 e  @& r; Y7 c7 @  ^

2 P0 X" f, r% `9 S上述条件确保了pdflush操作可以减轻系统中内存不足的压力。
; b. R% `5 w1 n  J& F! N3 e回写操作不会在达到这两个条件前停止,除非pdflush写回了所有的脏页,没有剩下的脏页可再被写回了。
& [0 l5 H' D2 W; Y6 W4 @5 u# P: {$ M& u3 Y$ e3 l  |" P& G* u9 I
要满足第二个目标,pdflush后台例程会被周期性唤醒(和空闲内存是否过低无关),# x: `9 J0 f( `4 n4 x& d
将那些在内存中驻留时间过长的脏页写出,确保内存中不会有长期存在的脏页。
. U$ u& k4 q$ c& M( Z加入系统发生崩溃,则内存会处于混乱之中,而那些在内存中还没来得及写回磁盘的脏页就会丢失,
% d% o1 Z4 X$ P) c& g所以周期性同步回写非常重要。  G0 G3 Z: _$ c, ]' l* ?
: X5 y4 |6 R) L+ A
在系统启动时,内核初始化一个定时器,让它周期地唤醒pdflush线程,随后使其运行函数wb_kupdate()。
: P6 k4 ^0 s2 O, L  o该函数将把所有驻留时间超过百分之dirty_expire_centisecs秒的脏页写回。) m6 {4 v! |' n4 o/ Q' o7 C- S
然后定时器将再次被初始化为百分之dirty_expire_ centisecs秒后唤醒pdflush线程。
- c- c5 Q+ T% g$ H1 n( ~总而言之,pdflush线程周期地被唤醒并且把超过特定期限的脏页写回磁盘。 / e8 c6 ^5 v+ ^
* D, m1 }  o% m0 u+ {( p
二、proc下的相关控制参数$ S3 P* _, q. C& b
系统管理员可以在/proc/sys/vm中设置回写相关的参数,也可以通过sysctl系统调用设置它们。+ @- b( M+ R& m( }) n, s4 o8 }

  J1 J2 |0 f9 l$ b8 Y1. /proc/sys/vm/dirty_ratio
6 Z( d9 Z4 Y* e* J# V$ X, T这个参数控制一个进程在文件系统中的文件系统写缓冲区的大小,单位是百分比,表示系统内存的百分比,, m( F5 z9 |7 r) d7 ?
表示当一个进程中写缓冲使用到系统内存多少的时候,再有磁盘写操作时开始向磁盘写出数据。* d- y1 x9 A% M/ i
增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。
2 |: w1 O, o# u3 d' {: p. \但是,当你需要持续、恒定的写入场合时,应该降低其数值.
# S* |' _; S& h2 Y! Z2 ~一般缺省是 40。5 c4 s4 @  k0 ^1 N# t) J
设置方法如下:
, o7 J; T0 M( ?- p4 P  zecho 30 >/proc/sys/vm/dirty_ratio1 U/ K! m6 w2 D8 P$ }
# H7 m  K2 Z" w/ D2 m# X% m+ v7 V
2. /proc/sys/vm/dirty_background_ratio
5 e, k5 R& i( ?/ }1 A" ~这个参数控制文件系统的pdflush进程,在何时刷新磁盘。单位是百分比,表示系统总内存的百分比,- ^# [: X0 \& ]  B  n4 K+ Y
意思是当磁盘的脏数据缓冲到系统内存多少的时候,pdflush开始把脏数据刷新到磁盘。
1 L3 W8 z6 X/ ^0 W7 B3 x! W+ N4 y增大会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。: Y6 t4 W3 I8 j1 G
但是,当你需要持续、恒定的写入场合时,应该降低其数值.0 l6 H# @3 g; V& X+ G3 X( L$ ^2 G
一般缺省是10。
7 x0 _+ G: x2 M% P设置方法如下:, H* {2 m' j' j) P9 c
echo 8 >/proc/sys/vm/dirty_background_ratio! N! C' c# D( W' u. m! T
+ T5 R( I" ?6 L8 A9 ^1 ?6 c3 K
3. /proc/sys/vm/dirty_writeback_centisecs  Y( r' s2 a( \0 v+ _. O! a
Pdflush写后台进程每隔多久被唤醒并执行把脏数据写出到硬盘。单位是 1/100 秒。) F) B% h7 ?- C" t! @
如果你的系统是持续地写入动作,那么实际上还是降低这个数值比较好,这样可以把尖峰的写操作削平成多次写操作。
/ M# h( b) j& k; M+ D* y3 f% ?3 A缺省数值是500,也就是 5 秒。7 R/ o! }0 C0 w6 u$ b
设置方法如下:% _& y4 U; y# x
# echo 200 >/proc/sys/vm/dirty_writeback_centisecs
  J+ R4 x8 x9 m2 s& }
) Z5 |' h! q* r7 R  \/ ^' Q: F, [4. /proc/sys/vm/dirty_expire_centisecs
4 }+ q* ?" {4 F% b* ^. h& z9 W- X这个参数声明Linux内核写缓冲区里面的脏数据多“旧”了之后,pdflush 进程就开始考虑写到磁盘中去。
4 _' a' ]) i+ B! r6 a单位是 1/100秒。, _8 i3 d9 {5 ~0 a# x) Z% B
对于特别重载的写操作来说,这个值适当缩小也是好的,但也不能缩小太多,因为缩小太多也会导致IO提高太快。6 J. L5 C5 k+ m4 s; Z. _/ f
缺省是 30000,也就是 30 秒的数据就算旧了,将会刷新磁盘。/ \( A& d/ y3 J. c: @
建议设置为 1500,也就是15秒算旧。
0 b: R8 ^% P# N. C5 k, |, q; Z设置方法如下:
& a  ~( B) a. M3 P2 }echo 1500 >/proc/sys/vm/dirty_expire_centisecs1 `! Q; E6 n4 W5 H3 Q, o; T

3 G9 M3 N0 I* X9 \" @' M' u8 w, A三、内核参数修改后的生效
. m4 ?: E. S$ B/ r/ zLinux在系统运行时修改内核参数(/proc/sys与/etc/sysctl.conf),而不需要重新引导系统,
0 c8 z* @: ~0 N$ U2 d3 `- G这个功能是通过/proc虚拟文件系统实现的。5 c% B+ |1 h$ u

+ i$ U8 @! ~4 ^% H( S# L在/proc/sys目录下存放着大多数的内核参数,并且设计成可以在系统运行的同时进行更改,
% v& w  j% g5 p" g2 K  I3 k可以通过更改/proc/sys中内核参数对应的文件达到修改内核参数的目的(修改过后,保存配置文件就马上自动生效),
; a3 o- n! x, I: T7 R9 F不过重新启动机器后之前修改的参数值会失效,所以只能是一种临时参数变更方案。6 N# a. S' }  }6 G1 o7 y( S- h& _4 S
(适合调试内核参数优化值的时候使用,如果设置值有问题,重启服务器还原原来的设置参数值了。简单方便。)7 Y5 O# ]  @2 }
9 A2 d1 _) f4 ~) v$ D
但是如果调试内核参数优化值结束后,需要永久保存参数值,( ]$ X0 I( \9 v, M4 D/ {* z
就要通过修改/etc/sysctl.conf内的内核参数来永久保存更改。
& _1 n6 S2 X: E% h/ f& |8 h但只是修改sysctl文件内的参数值,确认保存修改文件后,设定的参数值并不会马上生效,% D. J* V( N7 y: f% T9 t6 Q
如果想使参数值修改马上生效,并且不重启服务器,可以执行下面的命令:8 U$ D& Q! p, l; g2 X$ o
  # sysctl –p
' ^6 M3 U  Y/ ~5 s" N$ Y/ }
' q' \8 j( o# B) k, Y/ X下面介绍一下/proc/sys下内核文件与配置文件sysctl.conf中变量的对应关系:: z. B) ]9 R" u7 F0 Q
由于可以修改的内核参数都在/proc/sys目录下,所以sysctl.conf的变量名省略了目录的前面部分(/proc/sys)。
4 S  K- o+ I! H" D即将/proc/sys中的文件转换成sysctl中的变量依据下面两个简单的规则:
* Z3 ]0 a1 b0 c; X8 Q1.去掉前面部分/proc/sys8 I% f+ w$ K) J/ W1 k+ j
2.将文件名中的斜杠变为点+ s: s3 J* Y1 [/ a* W
  z; F; Z3 }" }1 [
这两条规则可以将/proc/sys中的任一文件名转换成sysctl中的变量名。
9 J# M: y+ t5 j5 s例如:6 f& q4 |, X' V1 @* w9 x
/proc/sys/net/ipv4/ip_forward =》 net.ipv4.ip_forward
- ~. i6 R  ~5 L. i/proc/sys/kernel/hostname =》 kernel.hostname
7 j' g  @* E! ?7 |0 b
5 E- s4 ~0 k. k; S3 y3 G4 z  y可以使用下面命令查询所有可修改的变量名
1 V) I0 V* C& v% o" u  # sysctl –a' i2 d8 [3 u$ K/ J. g7 o6 d

6 ^8 d' I! F" d% F" ?: u) t. k2 f: A; ~& S* X+ u$ ^3 k

该用户从未签到

2#
发表于 2020-4-17 18:37 | 只看该作者
pdflush进程详解

该用户从未签到

3#
发表于 2020-4-20 13:26 | 只看该作者
pdflush进程详解
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-10-26 00:13 , Processed in 0.125000 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表