目录

IO调度器的总体目标是希望让磁头能够总是往一个方向移动,移动到底了再往反方向走,这恰恰就是现实生活中的电梯模型,所以IO调度器也被叫做电梯 (elevator)而相应的算法也就被叫做电梯算法,而Linux中IO调度的电梯算法有好几种,一个叫做as(Anticipatory),一个叫做cfq(Complete Fairness Queueing),一个叫做deadline,还有一个叫做noop(No Operation),具体使用哪种算法我们可以在启动的时候通过内核参数elevator来指定。

I/O调度的4种算法

1.CFQ(完全公平排队I/O调度程序)

  • 特点:

    在最新的内核版本和发行版中,都选择CFQ做为默认的I/O调度器,对于通用的服务器也是最好的选择。

    CFQ试图均匀地分布对I/O带宽的访问,避免进程被饿死并实现较低的延迟,是deadline和as调度器的折中。

    CFQ对于多媒体应用(video,audio)和桌面系统是最好的选择。

    CFQ赋予I/O请求一个优先级,而I/O优先级请求独立于进程优先级,高优先级的进程的读写不能自动地继承高的I/O优先级。
  • 工作原理:

    CFQ为每个进程/线程,单独创建一个队列来管理该进程所产生的请求,也就是说每个进程一个队列,各队列之间的调度使用时间片来调度,以此来保证每个进程都能被很好的分配到I/O带宽.I/O调度器每次执行一个进程的4次请求。

2.NOOP(电梯式调度程序)

  • 特点:

    在Linux2.4或更早的版本的调度程序,那时只有这一种I/O调度算法。

    NOOP实现了一个简单的FIFO队列,它像电梯的工作主法一样对I/O请求进行组织,当有一个新的请求到来时,它将请求合并到最近的请求之后,以此来保证请求同一介质。

    NOOP倾向饿死读而利于写。

    NOOP对于闪存设备,RAM,嵌入式系统是最好的选择。

电梯算法饿死读请求的解释:

因为写请求比读请求更容易。

写请求通过文件系统cache,不需要等一次写完成,就可以开始下一次写操作,写请求通过合并,堆积到I/O队列中。

读请求需要等到它前面所有的读操作完成,才能进行下一次读操作.在读操作之间有几毫秒时间,而写请求在这之间就到来,饿死了后面的读请求。

3.Deadline(截止时间调度程序)

  • 特点:

    通过时间以及硬盘区域进行分类,这个分类和合并要求类似于noop的调度程序。

    Deadline确保了在一个截止时间内服务请求,这个截止时间是可调整的,而默认读期限短于写期限.这样就防止了写操作因为不能被读取而饿死的现象。

    Deadline对数据库环境(ORACLE RAC,MYSQL等)是最好的选择。

4.AS(预料I/O调度程序)

  • 特点:

    本质上与Deadline一样,但在最后一次读操作后,要等待6ms,才能继续进行对其它I/O请求进行调度。

    可以从应用程序中预订一个新的读请求,改进读操作的执行,但以一些写操作为代价。

    它会在每个6ms中插入新的I/O操作,而会将一些小写入流合并成一个大写入流,用写入延时换取最大的写入吞吐量。

    AS适合于写入较多的环境,比如文件服务器。

    AS对数据库环境表现很差。

查看当前系统支持的IO调度算法

[root@localhost ~]# dmesg | grep -i scheduler
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)

查看当前系统的I/O调度方法

cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]

临地更改I/O调度方法

#例如:想更改到noop电梯调度算法:
echo noop > /sys/block/sda/queue/scheduler

想永久的更改I/O调度方法

#修改内核引导参数,加入elevator=调度程序名
vi /boot/grub/menu.lst
#更改到如下内容:
kernel /boot/vmlinuz-2.6.18-8.el5 ro root=LABEL=/ elevator=deadline rhgb quiet

重启之后,查看调度方法

cat /sys/block/sda/queue/scheduler
noop anticipatory [deadline] cfq
#已经是deadline了

I/O调度程序的测试

本次测试分为只读,只写,读写同时进行。

分别对单个文件600MB,每次读写2M,共读写300次。

1.测试磁盘读

[root@test1 tmp]# echo deadline > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/sda1 of=/dev/null bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 6.81189 seconds, 92.4 MB/s
real 0m6.833s
user 0m0.001s
sys 0m4.556s
[root@test1 tmp]# echo noop > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/sda1 of=/dev/null bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 6.61902 seconds, 95.1 MB/s
real 0m6.645s
user 0m0.002s
sys 0m4.540s
[root@test1 tmp]# echo anticipatory > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/sda1 of=/dev/null bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 8.00389 seconds, 78.6 MB/s
real 0m8.021s
user 0m0.002s
sys 0m4.586s
[root@test1 tmp]# echo cfq > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/sda1 of=/dev/null bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 29.8 seconds, 21.1 MB/s
real 0m29.826s
user 0m0.002s
sys 0m28.606s

测试结果

第一 noop用了6.61902秒,速度为95.1MB/s

第二 deadline用了6.81189秒,速度为92.4MB/s

第三 anticipatory用了8.00389秒,速度为78.6MB/s

第四 cfq用了29.8秒,速度为21.1MB/s

2.测试写磁盘

[root@test1 tmp]# echo cfq > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/zero of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 6.93058 seconds, 90.8 MB/s
real 0m7.002s
user 0m0.001s
sys 0m3.525s
[root@test1 tmp]# echo anticipatory > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/zero of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 6.79441 seconds, 92.6 MB/s
real 0m6.964s
user 0m0.003s
sys 0m3.489s
[root@test1 tmp]# echo noop > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/zero of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 9.49418 seconds, 66.3 MB/s
real 0m9.855s
user 0m0.002s
sys 0m4.075s
[root@test1 tmp]# echo deadline > /sys/block/sda/queue/scheduler
[root@test1 tmp]# time dd if=/dev/zero of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 6.84128 seconds, 92.0 MB/s
real 0m6.937s
user 0m0.002s
sys 0m3.447s

测试结果

第一 anticipatory用了6.79441秒,速度为92.6MB/s

第二 deadline用了6.84128秒,速度为92.0MB/s

第三 cfq用了6.93058秒,速度为90.8MB/s

第四 noop用了9.49418秒,速度为66.3MB/s

3.测试同时读/写

[root@test1 tmp]# echo deadline > /sys/block/sda/queue/scheduler
[root@test1 tmp]# dd if=/dev/sda1 of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 15.1331 seconds, 41.6 MB/s
[root@test1 tmp]# echo cfq > /sys/block/sda/queue/scheduler
[root@test1 tmp]# dd if=/dev/sda1 of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 36.9544 seconds, 17.0 MB/s
[root@test1 tmp]# echo anticipatory > /sys/block/sda/queue/scheduler
[root@test1 tmp]# dd if=/dev/sda1 of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 23.3617 seconds, 26.9 MB/s
[root@test1 tmp]# echo noop > /sys/block/sda/queue/scheduler
[root@test1 tmp]# dd if=/dev/sda1 of=/tmp/test bs=2M count=300
300+0 records in
300+0 records out
629145600 bytes (629 MB) copied, 17.508 seconds, 35.9 MB/s

测试结果

第一 deadline用了15.1331秒,速度为41.6MB/s

第二 noop用了17.508秒,速度为35.9MB/s

第三 anticipatory用了23.3617秒,速度为26.9MS/s

第四 cfq用了36.9544秒,速度为17.0MB/s

ionice

ionice可以更改任务的类型和优先级,不过只有cfq调度程序可以用ionice。

有三个例子说明ionice的功能:

  1. 采用cfq的实时调度,优先级为7

    ionice -c1 -n7 -ptime dd if=/dev/sda1 of=/tmp/test bs=2M count=300&
  2. 采用缺省的磁盘I/O调度,优先级为3

    ionice -c2 -n3 -ptime dd if=/dev/sda1 of=/tmp/test bs=2M count=300&
  3. 采用空闲的磁盘调度,优先级为0

    ionice -c3 -n0 -ptime dd if=/dev/sda1 of=/tmp/test bs=2M count=300&

ionice的三种调度方法,实时调度最高,其次是缺省的I/O调度,最后是空闲的磁盘调度

ionice的磁盘调度优先级有8种,最高是0,最低是7

注意,磁盘调度的优先级与进程nice的优先级没有关系

一个是针对进程I/O的优先级,一个是针对进程CPU的优先级


  • Anticipatory I/O scheduler

    适用于大多数环境,但不太合适数据库应用。

  • Deadline I/O scheduler

    通常与Anticipatory相当,但更简洁小巧,更适合于数据库应用。

  • CFQ I/O scheduler

    默认IO调度器Default I/O scheduler,为所有进程分配等量的带宽,适合于桌面多任务及多媒体应用。

最新文章

  1. 【项目记录】-液化气配送app android版
  2. Sage Crm 权限原理分析
  3. 【.NET】Nuget包,把自己的dll放在云端
  4. PHP Ajax 跨域问题最佳解决方案
  5. block,inline和inlinke-block细节对比
  6. tokudb引擎磁盘空间不足导致写入失败的调查
  7. PHPCMS 标签与示例
  8. LeetCode Paint Fence
  9. float,double,decimal使用讨论
  10. 在HTML中优雅的生成PDF
  11. 233. Number of Digit One
  12. 怎么样Ubuntu正在使用root账号登录
  13. JDBC连接数据以及操作数据
  14. Qt Creator编译运行成功,但是显示系统找不到指定的文件(比如urlmon.dll动态链接库)
  15. 推荐六款炫酷的HTML5效果插件
  16. LeetCode174-Dungeon Game-数组,动态规划
  17. HDU-6153 A Secret 扩展KMP
  18. C#中Quartz的简单易懂定时任务实现
  19. .Net Core实现记录接口执行时间的中间件
  20. oracle中实现当前月减少或增加N个月

热门文章

  1. jquery——制作置顶菜单
  2. linux下.exe文件的安装与使用
  3. python3+Appium自动化07-滑动操作以及滑动方法封装
  4. 利用PyQt GUI显示图片、实时播放视频
  5. spring双列
  6. 现代java开发指南系列
  7. Django的路由层和视图层
  8. 12个非常不错的javascript类库
  9. 【Shell脚本学习25】Shell文件包含
  10. grunt + sass 使用记录