blockdev --getra /dev/sdb 返回值单位为512字节扇区数,非kb;例如返回8192表示8192×512=4096kb≈4mb,等价命令cat /sys/block/sdb/queue/read_ahead_kb直接显示kb值,更直观。

blockdev --getra 是最直接的查看方式,但要注意单位是 512 字节扇区,不是 KB —— 很多人误把返回值当 KB 看,结果调错一倍。
怎么用 blockdev 查看当前预读值
执行 sudo blockdev --getra /dev/sdb,返回一个整数,比如 8192。这不是 8192 KB,而是 8192 个 512 字节扇区,即 8192 × 512 = 4194304 字节 = 4096 KB ≈ 4 MB。
- 等价命令:
cat /sys/block/sdb/queue/read_ahead_kb—— 这个直接显示 KB 单位,更直观 - 批量查所有设备:
lsblk --output name,kname,ra,size,mountpoint,ra列就是预读 KB 值 - 注意:必须用 root 权限,普通用户执行
blockdev --getra会报Operation not permitted
blockdev --setra 设置预读时的单位陷阱
--setra 的参数单位和 --getra 完全一致:**512 字节扇区数**,不是字节、不是 KB。设成 4096 表示 4096 × 512 = 2 MB;设成 8192 才是 4 MB。
- 错误示范:
sudo blockdev --setra 4096 /dev/sdb→ 实际设为 2 MB,不是 4096 KB - 正确换算:想要 8 MB 预读,应传
16384(因为 8 × 1024 × 1024 ÷ 512 = 16384) - SSD 一般不需要大预读,设
256~1024(128 KB~512 KB)足够;机械盘顺序读多的场景可试4096~8192(2 MB~4 MB)
为什么 blockdev 设置重启后失效
因为 blockdev --setra 直接写内核块设备队列参数,属于运行时配置,不触碰任何配置文件或 udev 规则。
- 临时生效:适合测试不同预读值对某次大文件拷贝或数据库导入的影响
- 持久化方案只有两个靠谱路径:
/etc/rc.local里加命令(systemd 环境需确保 rc-local.service 启用),或写 udev rule(如/etc/udev/rules.d/60-blockdev-ra.rules中写ACTION=="add|change", KERNEL=="sdb", SUBSYSTEM=="block", RUN+="/sbin/blockdev --setra 4096 /dev/%k") - 别往
/etc/fstab或/etc/default/grub里硬塞 —— 它们不处理这个参数
预读值设太大反而拖慢性能的典型表现
不是所有“大文件读取”都适合开大预读。当应用存在大量随机小 IO 或内存紧张时,过大的预读会吃光页缓存、触发频繁 swap 或 writeback 延迟。
- 现象:
iostat -x 1显示await暴涨、%util接近 100%,但实际吞吐没提升,甚至下降 - 验证方法:对比
echo 3 > /proc/sys/vm/drop_caches清缓存后,分别用--setra 256和--setra 8192跑相同 dd 测试(dd if=/dev/sdb of=/dev/null bs=1M count=1000),看 real time 和iostat的rMB/s - 关键判断点:预读是否匹配真实访问模式 —— 顺序流式读才受益;跳着读、小文件密集读、写多读少的场景,预读基本无用,还占资源
预读本质是空间局部性的预测行为,它不理解你的业务逻辑。调参前先确认磁盘访问是不是真顺序、有没有足够空闲内存承接预读数据,比盲目调大数字重要得多。











