blockdev --setra预读优化和IO请求的大小

简介: 磁盘预读可以改善顺序读的性能,并且测试发现每个读请求的大小也受预读大小的影响,也就是发生了IO合并。 在每次8K的顺序读中,关闭预读时,每个IO是8个扇区(4K); 增大预读,每个IO大概等于预读大小,但最大是设备的单个IO大小的上限(这里是1024)。

磁盘预读可以改善顺序读的性能,并且测试发现每个读请求的大小也受预读大小的影响,也就是发生了IO合并。

在每次8K的顺序读中,关闭预读时,每个IO是8个扇区(4K); 增大预读,每个IO大概等于预读大小,但最大是设备的单个IO大小的上限(这里是1024)。 下面是详细的测试。

环境

台式机上的CentOS7.1 4核虚机
消费级SSD

准测试数据

dd if=/dev/zero of=testdata bs=8096 count=100000 

关闭预读的测试

  1. 关闭预读

    /sbin/blockdev --setra 0 /dev/mapper/centos-root
    /sbin/blockdev --setfra 0 /dev/mapper/centos-root 
  2. 清缓存

    sync
    echo 3 > /proc/sys/vm/drop_caches 
  3. 执行顺序读操作

    [root@node2 ~]# dd if=testdata bs=8192 count=100000 of=/dev/null
    98828+1 records in
    98828+1 records out
    809600000 bytes (810 MB) copied, 150.268 s, 5.4 MB/s 

    在没有预读的情况下,读取速度5.4 MB/s,说明每个IO大小是8个扇区(4KB),取的是iostat中途的值。

    [root@node2 ~]# iostat -xm 1 100
    avg-cpu:  %user   %nice %system %iowait  %steal   %idle
               0.00    0.00    8.22   15.38    0.00   76.39
    
    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 1390.00    0.00     5.43     0.00     8.00     0.91    0.65    0.65    0.00   0.65  90.70
    sdb               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    scd0              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    dm-0              0.00     0.00 1389.00    0.00     5.43     0.00     8.00     0.91    0.65    0.65    0.00   0.65  90.90
    dm-1              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    dm-2              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    dm-3              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    dm-6              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    dm-5              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
    dm-4              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00 

设置预读大小为256

256是RHEL6.x的默认值,读取速度达到21.1 MB/s

[root@node2 ~]# /sbin/blockdev --setra 256 /dev/mapper/centos-root
[root@node2 ~]# sync
[root@node2 ~]# echo 3 > /proc/sys/vm/drop_caches
[root@node2 ~]# dd if=testdata bs=8192 count=100000 of=/dev/null
98828+1 records in
98828+1 records out
809600000 bytes (810 MB) copied, 38.2959 s, 21.1 MB/s 

相应的每个读请求的大小也也通过IO合并扩大到了256扇区左右。(下面除avgrq-sz,avgqu-sz外,其它值每秒的波动很大,不可作为参考)

[root@node2 ~]# iostat -xm 1 100
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.00    0.00    0.50   24.81    0.00   74.69

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   38.00    0.00     4.75     0.00   256.00     2.00   51.32   51.32    0.00  26.37 100.20
sdb               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
scd0              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-0              0.00     0.00   38.00    0.00     4.75     0.00   256.00     2.00   51.32   51.32    0.00  26.37 100.20
dm-1              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-2              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-3              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-6              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-5              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-4              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00 

设置预读大小为2048

设置预读大小为2048后,读取速度达到30.6 MB/s

[root@node2 ~]# /sbin/blockdev --setra 2048 /dev/mapper/centos-root
[root@node2 ~]# sync
[root@node2 ~]# echo 3 > /proc/sys/vm/drop_caches
[root@node2 ~]# dd if=testdata bs=8192 count=100000 of=/dev/null
98828+1 records in
98828+1 records out
809600000 bytes (810 MB) copied, 26.4212 s, 30.6 MB/s 

相应的每个读请求的大小也扩大到了1024扇区左右。

[root@node2 ~]# iostat -xm 1 100
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.00    0.00    1.51   23.62    0.00   74.87

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   67.00    0.00    32.33     0.00   988.18     3.48   51.48   51.48    0.00  14.91  99.90
sdb               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
scd0              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-0              0.00     0.00   68.00    0.00    33.00     0.00   993.88     3.48   50.74   50.74    0.00  14.69  99.90
dm-1              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-2              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-3              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-6              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-5              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-4              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00 

 1024是这个设备每次读请求的最大扇区数,由于预读的大小是2048,所以可以看到IO队列深度提高到了3.48,比前面的256时的2高出将近1倍。

[root@node2 ~]# blockdev --getmaxsect  /dev/mapper/centos-root
1024 


结论


在单个应用进行同步读操作时,可以通过avgrq-sz和 avgqu-sz看出有没有进行预读优化,没有预读时通常avgrq-sz小于等于read()请求的size,avgqu-sz小于等于1。有预读时,avgrq-sz和avgqu-sz会相应增大,充分利用IO设备的处理能力。

参考

关于预读算法的说明可参考下面的第一篇文章,预读算法会尽量避免对随机读的预读,防止无效的预读。

  • http://os.51cto.com/art/200910/159067.htm
  • http://tech.hexun.com/2011-03-28/128268656.html
相关文章
POST 请求出现异常!java.io.IOException: Server returned HTTP response code: 400 for URL
POST 请求出现异常!java.io.IOException: Server returned HTTP response code: 400 for URL
915 0
|
4天前
|
NoSQL Java Linux
【Linux IO多路复用 】 Linux 网络编程 认知负荷与Epoll:高性能I-O多路复用的实现与优化
【Linux IO多路复用 】 Linux 网络编程 认知负荷与Epoll:高性能I-O多路复用的实现与优化
74 0
|
4天前
|
Java 大数据 数据库
【Spring底层原理高级进阶】Spring Batch清洗和转换数据,一键处理繁杂数据!Spring Batch是如何实现IO流优化的?本文详解!
【Spring底层原理高级进阶】Spring Batch清洗和转换数据,一键处理繁杂数据!Spring Batch是如何实现IO流优化的?本文详解!
|
4天前
|
Rust
【一起学Rust · 项目实战】命令行IO项目minigrep——重构优化模块和错误处理
【一起学Rust · 项目实战】命令行IO项目minigrep——重构优化模块和错误处理
41 0
|
4天前
|
监控 分布式数据库 流计算
Flink 异步IO优化任务
Flink 异步IO优化任务
43 0
|
6月前
|
移动开发 Java 数据处理
深入理解Java IO流:补充和优化
深入理解Java IO流:补充和优化
|
7月前
|
Java
网络通信优化-传统IO流及如何优化IO操作
网络通信优化-传统IO流及如何优化IO操作
|
8月前
|
缓存 Java Unix
Java使用NIO优化IO实现文件上传下载
Java使用NIO优化IO实现文件上传下载
212 0
|
9月前
|
存储 算法 大数据
倚天性能优化--基于倚天优化后的zstd在大数据场景应用:降低存储成本+提升重IO场景性能
倚天性能优化--基于倚天优化后的zstd在大数据场景应用:降低存储成本+提升重IO场景性能
|
10月前
|
NoSQL Redis 数据安全/隐私保护
Redis单线程处理IO请求性能瓶颈有哪些?
Redis单线程处理IO请求性能瓶颈有哪些?

热门文章

最新文章