Linux 调整顺序磁盘读取以提高性能

Linux 调整顺序磁盘读取以提高性能,linux,performance,io,linux-kernel,disk,Linux,Performance,Io,Linux Kernel,Disk,我正在按顺序从磁盘读取一个大文件,并试图在读取过程中理解iostat输出 文件大小:10 GB 读取缓冲区:4KB 预读(/sys/block/sda/queue/Read\u-ahead\u-kb):128 kb 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

我正在按顺序从磁盘读取一个大文件,并试图在读取过程中理解iostat输出

  • 文件大小:10 GB
  • 读取缓冲区:4KB
  • 预读(/sys/block/sda/queue/Read\u-ahead\u-kb):128 kb
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
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   495.32    10.78   12.15    4.76  265.83   2.36 100.00
计算I/O请求的平均大小=(rMB/s除以r/s)得到约128 KB的预读值。这似乎表明,虽然读系统调用指定了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     0.00  833.00   14.00   103.88     0.05   251.30     6.07    5.69    2.33 205.71  1.18 100.00
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   495.32    10.78   12.15    4.76  265.83   2.36 100.00
同样,与预读匹配的平均I/O请求大小为256 KB

这一直持续到我将512kb设置为预读值,当我将预读值提高到1024kb时,它就不起作用了——I/O请求的平均大小仍然是512kb。将max_sectors_kb(每个I/O请求的最大数据量)从默认值512 kb增加到1024 kb也没有帮助


为什么会发生这种情况?理想情况下,我希望尽可能降低读取IOPS,并在每个I/O请求中读取更多数据(每个请求大于512 KB)。此外,在所有情况下,我的磁盘利用率都达到了100%——我想限制自己以50-60%的磁盘利用率和良好的顺序吞吐量进行读取。简而言之,顺序读I/O的优化应用程序/内核设置是什么。

在1024kb的情况下,预读不起作用的原因应该是硬盘的扇区大小是512kb。请使用命令“fdisk-l”检查硬盘扇区大小。
即使更改了预读大小和最大扇区大小参数,IO的实际大小仍然不超过硬件IO大小(扇区大小)。

I/O调度程序算法可能在这方面有发言权。据介绍,
read\u-ahead\u-kb
与noop调度器配合使用效果最佳。Noop在调度方面做的不多,因此对块层参数的反应更好。要查看内核当前正在使用的I/O调度程序,请执行以下操作:
cat/sys/block//queue/scheduler
。Adaptive readahead还将干扰读取的数据量。根据,通过将
POSIX_FADV_RANDOM
标志传递到
POSIX_fadvise()
系统调用,可以关闭自适应预读。@bytefire-你很正确-使用noop调度程序并增加读取头和最大扇区kb,我能够将读取请求的平均大小增加到3.2MB/s(25次读取中为80MB/s).这很有趣-有关于这方面的文件吗?另外,为了防止用其他随机读取中断顺序读取的范围,磁盘接受较大的读取是否有益?通常,Linux内核将扇区大小视为512字节,如果磁盘具有不同的扇区大小,低级块设备驱动程序进行必要的转换。一个相关问题:队列/预读kb的限制是什么?在自动测试期间,我发现
0
是可以接受的,
4
也是可以接受的,但是
1
不是。我读到这个值必须至少是设备的块大小,所以对于512字节的块,1k应该是可以的,对吗?