我正在从磁盘中顺序读取一个大文件,并尝试iostat
在读取过程中理解输出。
输出iostat
如下
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 0.00 833.00 14.00 103.88 0.05 251.30 6.07 5.69 2.33 205.71 1.18 100.00
Run Code Online (Sandbox Code Playgroud)
计算 I/O 请求的平均大小 =(rMB/s 除以 r/s)得出 ~ 128 KB,这是预读值。这似乎表明,虽然 read 系统调用指定了 4KB 缓冲区,但实际磁盘 I/O 是根据预读值发生的。
当我将预读值增加到256KB时,iostat
输出如下
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 28.00 412.00 12.00 102.50 0.05 …
Run Code Online (Sandbox Code Playgroud) 我需要能够从文件中顺序读取数据,同时不将正在读取的数据存储在页面缓存中,因为预计不会再次读取文件内容,并且因为盒子上存在内存压力(想要将宝贵的内存用于有用的磁盘 I/O 缓存)。
我的问题是关于如何优化这些读取。由于我知道正在读取的数据按顺序放置在磁盘上(减去碎片),我希望能够提前读取(通过增加 /sys/block/sda/queue/read_ahead_kb)但我不确定这是否将带来任何好处,因为我必须使用 posix_fadvise(带有 POSIX_FADV_DONTNEED 标志)来防止正在读取的数据存储在页面缓存中。
是否会因为从页面缓存中删除数据的提示而简单地丢弃预读数据?