@
pagxir 有一个非常简单的方法能测试 readahead 有没有生效(
就是把它关闭了
echo 0 > /sys/block/sda/queue/read_ahead_kb
然后再运行 dd if=/dev/sda of=/dev/null bs=1M
16+0 records in
16+0 records out
16777216 bytes (16.0MB) copied, 1.039096 seconds, 15.4MB/s
而设置成默认 128 是这个效果
/ # echo 128 > /sys/block/sda/queue/read_ahead_kb
/ # dd if=/dev/sda of=/dev/null bs=1M
16+0 records in
16+0 records out
16777216 bytes (16.0MB) copied, 0.127543 seconds, 125.4MB/s
而用极为夸张的 1048576 则是这个效果(可见不是越大越好)
/ # echo 1048576 > /sys/block/sda/queue/read_ahead_kb
/ # dd if=/dev/sda of=/dev/null bs=1M
16+0 records in
16+0 records out
16777216 bytes (16.0MB) copied, 0.121848 seconds, 131.3MB/s
(测试中的磁盘是 qemu 参数 -drive file=/tmp/test.img,format=raw 挂载的,qemu 本身没有启用 kvm 模式,因此性能较低但是比较稳定)
此外关于 gzip 管道的问题,我也做了一个测试,当磁盘速度不是瓶颈(且 readahead 没被禁用的情况下)
/ # time dd if=/dev/sda of=/dev/null bs=1048576
16+0 records in
16+0 records out
16777216 bytes (16.0MB) copied, 0.129122 seconds, 123.9MB/s
real 0m 0.14s
user 0m 0.00s
sys 0m 0.13s
直接用 gzip
/ # time sh -c 'gzip -c /dev/sda > /dev/null'
real 0m 0.87s
user 0m 0.76s
sys 0m 0.10s
加个 dd 管道
/ # time sh -c 'dd if=/dev/sda bs=1048576 | gzip > /dev/null'
16+0 records in
16+0 records out
16777216 bytes (16.0MB) copied, 1.008238 seconds, 15.9MB/s
real 0m 1.03s
user 0m 0.79s
sys 0m 0.23s
可见速度反而还下降了(我也测试过其他 bs 值,几乎不对结果产生影响,始终大于 1 秒,这个模拟下 1048576 已经是接近最优的值了)
有趣的是,如果这时候用 dd 的 direct 模式手动绕过缓存
/ # time sh -c 'dd if=/dev/sda bs=1048576 iflag=direct | gzip > /dev/null'
16+0 records in
16+0 records out
16777216 bytes (16.0MB) copied, 0.959065 seconds, 16.7MB/s
real 0m 0.98s
user 0m 0.78s
sys 0m 0.18s
就小于 1 秒了,可惜还是没有 gzip 直接压缩快(