说明
大家都知道磁盘IO调度器平衡了IO吞吐量和IO响应时间,针对不同的磁盘类型,HDD或SSD,提供了相应的优化调度方法。通常,内核编译时候,选择CFQ作为默认的IO scheduler,适合于HDD设备。如果我们使用SSD设备(如现在主流的笔记本),则可以在Linux启动的时候,通过Grub向内核传递 elevator=deadline
来更改访问SSD设备的IO scheduler。
但是,在线上的服务器,有些针对特定应用采用的混合磁盘类型的服务器,如采用部分SSD磁盘,部分HDD磁盘,则采用这种一刀切调整IO scheduler就不合理,不论是采用CFQ
还是deadline
都无法完全满足要求。
这就要求我们的设置方法能够根据服务器安装的磁盘类型,自动检测并采用对应的IO scheduler。
动态调整混合存储的io scheduler
找出系统所有磁盘设备
ls /sys/block/ | grep sd
参考 Find all storage devices attached to a Linux machine。注意:如果要找到所有分区可以查看
/proc/partitions
。注意,块设备有很多,其中磁盘设备以sd
开头。
分辨设备是SSD还是HDD
设备是SSD还是HDD可以通过cat /sys/block/sda/queue/rotational
内容来区分,其中内容为1
表示是传统磁盘HDD,如果内容是0
则表示SSD
设置SSD设备io scheduler
可以on fly
方式动态修改SSD设备的io scheduler
echo deadline > /sys/block/sda/queue/scheduler
结合脚本命令设置磁盘io scheduler
- 扫描所有磁盘检查是否是SSD(这个命令也就是先验证一遍是否是SSD,为后面准备批量调整)
for i in `ls /sys/block/ | grep sd`;do ( if [[ `cat /sys/block/$i/queue/rotational` == 0 ]]; then echo "$i ok";else echo "$i ng";fi );done
可以看到输出内容符合预期
sda ok
sdb ng
sdc ng
sdd ng
sde ng
sdf ng
sdg ng
sdh ng
sdi ng
sdj ng
sdk ok
sdl ok
- 现在我们可以一次性调整好所有符合要求的SSD的io scheduler为
deadline
,HDD的io scheduler为cfq
(需要使用root
权限调整)
for i in `ls /sys/block/ | grep sd`;do ( if [[ `cat /sys/block/$i/queue/rotational` == 0 ]]; then echo deadline > /sys/block/$i/queue/scheduler;else echo cfq > /sys/block/$i/queue/scheduler;fi );done
- 验证调整是否成功
for i in `ls /sys/block/ | grep sd`;do ( echo $i; cat /sys/block/$i/queue/scheduler );done
检查结果符合预期
sda
noop anticipatory [deadline] cfq
sdb
noop anticipatory deadline [cfq]
sdc
noop anticipatory deadline [cfq]
sdd
noop anticipatory deadline [cfq]
sde
noop anticipatory deadline [cfq]
sdf
noop anticipatory deadline [cfq]
sdg
noop anticipatory deadline [cfq]
sdh
noop anticipatory deadline [cfq]
sdi
noop anticipatory deadline [cfq]
sdj
noop anticipatory deadline [cfq]
sdk
noop anticipatory [deadline] cfq
sdl
noop anticipatory [deadline] cfq
持久化调整混合存储的io scheduler
Linux 的 udev rule 可以针对不同的磁盘类型设置io scheduler,方法如下
- 编辑
/etc/udev/rules.d/60-ssd-scheduler.rules
内容如下
# set deadline scheduler for non-rotating disks
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="deadline"
- 刷新udev规则
udevcontrol reload_rules
- 以上配置就使得当系统重启或者插拔SSD磁盘时,系统就会自动设置好SSD的io scheduler。可以重启一台NC验证一下