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

pdflush进程详解

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
大家知道,在linux操作系统中,写操作是异步的,即写操作返回的时候数据并没有真正写到磁盘上,
8 ?- _' ^4 \/ r5 }4 ~' r3 I
; Q5 F% U0 F/ [. D2 i/ E而是先写到了系统cache里,随后由pdflush内核线程将系统中的脏页写到磁盘上,在下面几种情况下,8 l: l& c. u- B9 {0 c" P2 U( s& R4 N
系统会唤醒pdflush回写脏页:
/ p- C- M8 z7 w6 t0 w1 、定时方式:
* Z' u6 w0 C4 b! G. E     定时机制定时唤醒pdflush内核线程,周期为/proc/sys/vm/dirty_writeback_centisecs ,单位' g+ ]) p% p5 @6 z
是(1/100)秒,每次周期性唤醒的pdflush线程并不是回写所有的脏页,而是只回写变脏时间超过
2 k2 [8 m. a' B8 b" a' V* m% T  S/proc/sys/vm/dirty_expire_centisecs(单位也是1/100秒)。
+ e3 s% \: V, M2 V" T注意:变脏的时间是以文件的inode节点变脏的时间为基准的,也就是说如果某个inode节点是10秒前变脏的,+ b8 ?3 ~& \% ]% [+ K5 _
pdflush就认为这个inode对应的所有脏页的变脏时间都是10秒前,即使可能部分页面真正变脏的时间不到10秒,
9 y/ j4 W. ]7 a- H$ w; K细节可以查看内核函数wb_kupdate()。8 G8 _; w! j) q5 h% Z/ ~8 y
9 i& ?  U0 i( v% t/ g! `$ @
2、 内存不足的时候:
( g- L* w  L6 ~  ]; ~    这时并不将所有的dirty页写到磁盘,而是每次写大概1024个页面,直到空闲页面满足需求为止。' g4 @  n- a# ^$ F7 i. Q+ x$ M1 x
, f0 D! R. H5 d8 |
3 、写操作时发现脏页超过一定比例:" ]% p! `3 }. V/ f" G
    当脏页占系统内存的比例超过/proc/sys/vm/dirty_background_ratio 的时候,write系统调用会唤醒
$ e9 ?# c1 B: L2 t: W0 F' Updflush回写dirty page,直到脏页比例低于/proc/sys/vm/dirty_background_ratio,但write系统调
; |8 V& e. i. L. `/ |6 B+ _3 S" ?用不会被阻塞,立即返回。当脏页占系统内存的比例超过/proc/sys/vm/dirty_ratio的时候, write系
* j! i0 |6 Y. w, l* K5 `% u统调用会被被阻塞,主动回写dirty page,直到脏页比例低于/proc/sys/vm/dirty_ratio,这一点在/ n! ^% s. l9 c) H8 Q9 j+ _
2.4内核中是没有的。
# o! i- z" B& D8 O/ m" p5 u1 R/ U* Y2 }# D, S- w& s$ z
4 、用户调用sync系统调用:
) \; p7 w) n( _; S    这是系统会唤醒pdflush直到所有的脏页都已经写到磁盘为止。& t; S2 c# S& _5 a6 z
' ^0 H( {2 G% X% i8 K

- i* K2 T$ D& ]8 O9 K1 u6 N( O一、简介
2 F  V6 o( ^; V! x- |由于页高速缓存的缓存作用,写操作实际上会被延迟。
" [. N+ u. w" ?" a8 b5 V% C当页高速缓存中的数据比后台存储的数据更新时,那么该数据就被称做脏数据。$ P5 Q% l" S: B. Z
在内存中累积起来的脏页最终必须被写回磁盘。
0 s, \) p. e2 R6 H, R& s4 J' i
' J) ^/ P  {  c在以下两种情况发生时,脏页被写回磁盘:) W. Q0 i$ Y- Z
.  当空闲内存低于一个特定的阈值时,内核必须将脏页写回磁盘,以便释放内存。
' m+ f3 O4 y  n4 x' N0 d# e% |0 r.  当脏页在内存中驻留时间超过一个特定的阈值时,内核必须将超时的脏页写回磁盘,' F+ K6 B: l* w4 y) m3 T
   以确保脏页不会无限期地驻留在内存中。
! ^0 `# T0 {* e# y: o9 U- p  J
6 E0 @4 `# O# d: R上面两种工作的目的完全不同。
6 E4 K: r5 r- L* n; ?1 t& R实际上,在老内核中,这是由两个独立的内核线程分别完成的。
. o/ R+ U3 I* p; R但是在2.6内核中,由一群内核线程—pdflush后台回写例程—统一执行两种工作。
0 n7 ~6 s" E) s6 X+ ]8 i' T3 O+ u0 J6 k" b7 F4 Y& {
我们来看看这两个目标是如何具体实现的。: h+ Z) M- G1 t# c- i# D0 Q
首先,当系统中的空闲内存低于一个特定的阈值时,pdflush线程将脏页刷新回磁盘。
6 c7 p2 b4 N9 `2 f3 D该后台回写例程的目的在于在可用物理内存过低时,释放脏页以重新获得内存。
- m; n! {3 B4 ]! ^4 P" S特定的内存阈值可以通过dirty_background_ratio参数设置。
& W1 T5 s3 X% ~- Y( k& u( x8 _当空闲内存比阈值dirty_ background_ratio还低时,内核便会调用函数wakeup_bdflush()唤醒一个pdflush线程,
' h) v- [; _4 s5 E0 ]  t随后pdflush线程进一步调用函数background_writeout()开始将脏页写回磁盘。% W' h/ u, A/ R5 v  \2 |8 v( X3 N9 S
函数background_ writeout()需要一个长整型参数,该参数指定试图回写的页面数目。
8 r) \% C- o. F2 |
( w. g* W, `: [' W* S( @函数background_writeout()会连续地写出数据,直到满足以下两个条件:4 w, |) v" W: N( |9 r: s$ O- C% Y
.  已经有指定的最小数目的页被写出到磁盘。
8 }9 y8 A6 a6 z8 M6 b.  空闲内存数已经回升,超过了阈值dirty_background_ratio。7 W8 @( ^. n; j7 q, p; w& j* X4 I
" |% P- l- }. o; w( Y
上述条件确保了pdflush操作可以减轻系统中内存不足的压力。3 s* {5 K: O% b( ~
回写操作不会在达到这两个条件前停止,除非pdflush写回了所有的脏页,没有剩下的脏页可再被写回了。
# s3 u& r! j5 `- ]6 N
% y$ U* |# }7 i+ T4 r要满足第二个目标,pdflush后台例程会被周期性唤醒(和空闲内存是否过低无关),- w- v3 l( N- W* U  i0 f5 s! C( e
将那些在内存中驻留时间过长的脏页写出,确保内存中不会有长期存在的脏页。8 m" l7 P2 ?- p0 R
加入系统发生崩溃,则内存会处于混乱之中,而那些在内存中还没来得及写回磁盘的脏页就会丢失,8 f7 N2 w- m% G
所以周期性同步回写非常重要。) }2 t; w+ C" Y0 P3 N- P, t

+ a, I1 {- @7 M) q1 R  a3 s在系统启动时,内核初始化一个定时器,让它周期地唤醒pdflush线程,随后使其运行函数wb_kupdate()。
. Z9 x  Y1 G7 e该函数将把所有驻留时间超过百分之dirty_expire_centisecs秒的脏页写回。3 E5 U# o1 E8 r5 `
然后定时器将再次被初始化为百分之dirty_expire_ centisecs秒后唤醒pdflush线程。
9 a, l) ]* p. R9 e; g4 R  }, F; K总而言之,pdflush线程周期地被唤醒并且把超过特定期限的脏页写回磁盘。
4 b0 B0 ?- `% R8 G' \+ ]" D5 p; I! g5 g1 e$ X$ Y6 W6 G9 K  w2 z
二、proc下的相关控制参数, i. _  h. |/ p* X, j  D1 }
系统管理员可以在/proc/sys/vm中设置回写相关的参数,也可以通过sysctl系统调用设置它们。
9 l! _9 b* @# Z/ a. B3 z4 v% ^" V% h5 _$ i
1. /proc/sys/vm/dirty_ratio
8 z$ D  @0 S; {# p1 C这个参数控制一个进程在文件系统中的文件系统写缓冲区的大小,单位是百分比,表示系统内存的百分比,
3 _, F# z1 ^- X3 \7 K0 `) T表示当一个进程中写缓冲使用到系统内存多少的时候,再有磁盘写操作时开始向磁盘写出数据。
8 ]) O2 o9 B1 c" q: Q, t) \增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。1 c8 \, A# ?& j
但是,当你需要持续、恒定的写入场合时,应该降低其数值.; z! @: x+ n7 `: X# V' a5 q! i
一般缺省是 40。
0 |5 r9 c( U$ Z+ M$ g, L% ?设置方法如下:- z# t2 w+ q7 N$ o  l: m& r
echo 30 >/proc/sys/vm/dirty_ratio' ?; s4 p2 o7 a7 D9 X# ?

9 Q6 h5 o1 V# c4 d' \6 L/ ?2. /proc/sys/vm/dirty_background_ratio
' A, W0 l8 ?1 Q5 ^这个参数控制文件系统的pdflush进程,在何时刷新磁盘。单位是百分比,表示系统总内存的百分比,4 ~; ^8 {$ f9 ?
意思是当磁盘的脏数据缓冲到系统内存多少的时候,pdflush开始把脏数据刷新到磁盘。' [1 s7 c- X% d' n7 `, m8 j2 \
增大会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。! p7 O* s2 c1 Y4 E8 b0 ]
但是,当你需要持续、恒定的写入场合时,应该降低其数值.
( }4 e( T$ R: c+ \% x, R8 I4 R一般缺省是10。% Y: p$ j# \8 M2 L" V( }! d
设置方法如下:* ]- {2 S: j$ ^: h
echo 8 >/proc/sys/vm/dirty_background_ratio- N  N& ~; N" t; L2 N

% r: M. O4 X) q3 i- ?3. /proc/sys/vm/dirty_writeback_centisecs7 ?* C" z7 C' y( z5 j. Z/ ?
Pdflush写后台进程每隔多久被唤醒并执行把脏数据写出到硬盘。单位是 1/100 秒。& a  [& a( R0 R- X- T" F" i
如果你的系统是持续地写入动作,那么实际上还是降低这个数值比较好,这样可以把尖峰的写操作削平成多次写操作。. ~1 L. `0 T  @* P( R) ]
缺省数值是500,也就是 5 秒。
) B% q  {" O+ s9 l设置方法如下:
; b1 O. _) G* M. q# echo 200 >/proc/sys/vm/dirty_writeback_centisecs# g0 l1 ]  L% `( d! {, Y

$ W" F% [# y4 f4. /proc/sys/vm/dirty_expire_centisecs
0 x) U2 U# _" U1 ]0 u这个参数声明Linux内核写缓冲区里面的脏数据多“旧”了之后,pdflush 进程就开始考虑写到磁盘中去。9 w" w& B1 Z! I0 ]4 ^4 L% D
单位是 1/100秒。
) Y5 h; a$ k4 D对于特别重载的写操作来说,这个值适当缩小也是好的,但也不能缩小太多,因为缩小太多也会导致IO提高太快。
" N0 X  D# H- |$ ^$ I0 z6 }, i1 |缺省是 30000,也就是 30 秒的数据就算旧了,将会刷新磁盘。) k" E9 P( h3 ~' @/ s$ O
建议设置为 1500,也就是15秒算旧。
3 Y2 k* f% M! v* m设置方法如下:# W, T/ I" |3 j; M) r9 o8 p* u
echo 1500 >/proc/sys/vm/dirty_expire_centisecs
' c2 N( u2 L) F) p- R/ M$ K& [+ M- _" v* O: A! h" ^
三、内核参数修改后的生效
! k! p; @. h6 j+ H- xLinux在系统运行时修改内核参数(/proc/sys与/etc/sysctl.conf),而不需要重新引导系统,4 P6 f" B5 O( }
这个功能是通过/proc虚拟文件系统实现的。0 }$ O. i8 `1 C' x
1 y# w4 _. x, b1 H4 ?' ^" m: `
在/proc/sys目录下存放着大多数的内核参数,并且设计成可以在系统运行的同时进行更改, : [% \5 q3 k8 [0 t/ \* c
可以通过更改/proc/sys中内核参数对应的文件达到修改内核参数的目的(修改过后,保存配置文件就马上自动生效),
( F% I" I0 O' y/ E8 N9 G8 d不过重新启动机器后之前修改的参数值会失效,所以只能是一种临时参数变更方案。
! y. ~" [" ^* `, P# X4 e(适合调试内核参数优化值的时候使用,如果设置值有问题,重启服务器还原原来的设置参数值了。简单方便。)
' g4 N5 i& g  r! L/ j7 ]: e# k$ J' f. x8 b4 n  v% i9 t  H
但是如果调试内核参数优化值结束后,需要永久保存参数值,
: [% Z+ t9 L0 t+ r! W就要通过修改/etc/sysctl.conf内的内核参数来永久保存更改。& f$ b. I4 Q7 v; J' r
但只是修改sysctl文件内的参数值,确认保存修改文件后,设定的参数值并不会马上生效,4 t- C) h6 Y5 c, Z
如果想使参数值修改马上生效,并且不重启服务器,可以执行下面的命令:* s; S- Z5 z/ L" K# I
  # sysctl –p
8 A9 W/ L& o4 x* T& ?4 g
5 \% v$ h& H: E) `& J+ B1 \. q2 F下面介绍一下/proc/sys下内核文件与配置文件sysctl.conf中变量的对应关系:
; \7 a  \) S0 P5 ]* K由于可以修改的内核参数都在/proc/sys目录下,所以sysctl.conf的变量名省略了目录的前面部分(/proc/sys)。/ I( B, j. V9 }) A  F' I4 V* W
即将/proc/sys中的文件转换成sysctl中的变量依据下面两个简单的规则:- N2 H9 E- x1 J. `4 t( }5 O
1.去掉前面部分/proc/sys
7 l7 t5 t8 h  k3 L4 E( G0 S. ^6 d. P2.将文件名中的斜杠变为点( V5 V# P5 W5 `

6 X8 X! E* V4 h  t. x; A这两条规则可以将/proc/sys中的任一文件名转换成sysctl中的变量名。
4 I0 }& E1 N0 j/ c- S: I1 U6 g例如:, J+ K8 c2 O: e
/proc/sys/net/ipv4/ip_forward =》 net.ipv4.ip_forward1 i: c% r" M" w/ z: {% x1 ?) z
/proc/sys/kernel/hostname =》 kernel.hostname
: q, e! Z# @0 Q8 k) `# T( V! t$ J/ K, O- e0 \0 A* m5 v
可以使用下面命令查询所有可修改的变量名$ P7 S, i4 g$ V; g- V
  # sysctl –a" a- C- a* P* Z' i; C5 d
. E5 x- d* c6 T

2 v0 ?4 l5 q0 `; X6 f

该用户从未签到

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

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-26 00:29 , Processed in 0.156250 second(s), 23 queries , Gzip On.

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

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

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