■ I/O, iowait 19:41
- 書き出しはページキャッシュに PG_Dirty フラグを立てるだけ。
- Linux ではデフォルトで pdflush が writeback するタイミングは 5秒おき
- sysctl の vm.dirty_writeback_centisecs = 500
- ディスクとの同期は5秒に一回
- tail -f とかで見てる内容はページの内容。5秒おきで書き込まれてるのでないように見えるのはページキャッシュを見てるから。
というのがログが豪快に書かれても tail -f でほぼリアルタイムに見えるけど、ぜんぜん平気な理由。実際、
#!/usr/local/bin/perl
use strict;
use warnings;
use IO::File;
use Time::HiRes qw/usleep/;
use constant DATA => "12345678" x 128;
my $io = IO::File->new("/home/naoya/tmp/test.dat", 'w') or die $!;
while (1) {
$io->syswrite(DATA);
usleep(100);
}
と 0.1 秒ごとに stdio 無視でファイルに書き込む処理を走らせて vmstat してもやはり bo 値は 5秒に一回。
他。
という前提で
- kupdate は一定時間ごとに起床して dirty なキャッシュを書き出す
- 一方 bdflush = background_writeback は空きページが少なくなってきたときに起床される
というのを加味して考える。(2.6 では kupdate + bdflush = pdflush)
- メモリが十分にあるとき
- ほぼすべてのデータがページキャッシュに載っているので read はほぼメモリから。 → iowait なし
- メモリ十分で空きページは常にあるので dirty ページの書き出しはほぼ5秒に一回の kupdate で賄える
- メモリが足りない / read 中心の場合
- read がときどきディスクに対して発生する → iowait が発生する。
- write はあまりないので dirty ページの書き出しは kupdate で事足りる。
- メモリが足りない、write がたくさん発生してる場合
- write が多いので dirty なページがたくさんできる
- メモリが足りないので空きページが十分に確保できない。kupdate だけでは事足りず bdflush の手を借りる
- bdflush が頻繁に起床するためブロックデバイスへの書き込み要求が高頻度になる
- 他方で read しようにもブロックデバイスに write も行っていてなかなか読み取りが完了しない → write が原因で iowait が長くなる
ということが言える。
ということは write が多いホストでもメモリを十分に積んでおけば pdflush によるディスクとの同期を起点とした read 遅延を発生させることもなく iowait は発生しない。
これで合ってるよね?
# ご協力感謝。 > d:id:hideoki