Linux的IO调度机制浅析

现代计算机体系中,磁盘的速度和CPU的速度差距太大了,如果简单的将系统的IO请求按照请求的顺序进行顺序处理的话,系统的IO开销将导致系统的效率十分的低下,因此就需要将IO请求进行合理的安排,Linux系统在这一方面主要通过两种机制实现其一是各种层次的缓存,然后就是IO调度。IO调度的算法和磁盘的寻址原理无法分离,所以先简单看一下磁盘寻址原理,这个百度一下就可以找到很多这里就是简单说下。

磁盘寻址

常见的硬盘都是由许多个盘片组成重叠同心圆盘,每一个磁盘由磁盘、磁轴和读写头组成,要在硬盘上找到一个准确的地址需要磁柱(cylinder)、磁头(head)和扇区(sector)三个坐标这就是CHS寻址。而且现代的磁盘这部分的工作是由硬盘的固件完成的,硬盘固件接受逻辑块号由固件将逻辑块到chs进行一一映射,而操作系统访问采用块编号访问磁盘的特定地址,这就是逻辑块寻址(LBA),并且逻辑块的编号到硬盘CHS的映射往往也是顺序的。

所以起初的IO调度程序主要的任务就是减少磁头移动的距离,就如同一个快递员在城市中派送快递一样,他会安排一个合理的顺序去派件,同一个小区的快件会在一次派件时一起完成。反应在IO调度程序中就是合并排序。合并就是将一个小区的快递从中转站全部集中来;排序就是对派送顺序的优化安排,就是尽量的减少派送总距离从而提高自己的派送效率。这个原理同电梯的调度相同,所以最早的IO调度算法本称为“电梯算法”。其原理就是保证磁头的线性移动,就像电梯会是 1、3、4、5、8、9或9、7、5、3、2、1 这样的顺序停止,虽然可能3楼的人后按了楼层按键。这个算法有个明显的问题就是如果不停的有新的物理顺序靠前的IO请求到来将导致靠后的请求被长时间的等待。然后就有了新的IO调度程序来解决以上问题以优化性能。

Deadline IO调度

同电梯算法比,此机制保留了IO请求的排序后的IO请求队列,额外的引进了两个队列均按请求时间的前后排序,一个为读请求,一个为写请求。一个新的请求到来时会按顺序的先放到标准队列中合适的位置,而再根据操作类型不同放到新增读写队列其中一个的末尾,读和写队列有着不同的IO请求deadline时间限制,一般读为500ms,写为5秒。然后此时IO调度程序平时行为就如同前面的调度算法一样从标准队列中一个个的按顺序处理,不同的是当读或写队列中任何一个请求deadline时间到来时,就会转而服务这个到期的请求,从而解决电梯算法的“饿着”某些请求的问题。

Anticipatory IO调度

此调度算法也是针对Deadline IO调度算法的一种优化,因为在Linux下读取操作是同步且同步化的,只有前一个读取请求返回了才可以送出下一个读请求,所以deadlineIO调度会有一个糟糕情况就是,当由一系列的物理相关的读请求出现时(从应用分析这种场景还比较常见)就会出现续读写头来回运动的情况,因为当第一个读请求送出并到期IO调度磁头需要先服务于这请求,然后回去继续普通的IO请求,此时与之前的读相邻的第二个读请求又来了,但是此时读写头已经运动回正常队列的请求地址了,然后等这个读请求到期就会发生和第一个读请求一样的情况了,所以如果正常队列的IO请求与当前请求的物理位置差的很远的话,这就是deadline算法的最坏情况,所以就有了Anticipatory IO调度算法,他的机制也很简单,在服务完一个到期的读时进行一个合适的时间等待,如果新提交的读请求来到就可以快速完成读,正如其名是一个预测性质的算法是概率学优化。

CFQ IO调度

称为完全公平调度算法,它为每个进程维护了一个IO请求队列,IO调度程序会以轮询的方式服务每个进程队列的请求,直到时间片用完或者无IO请求,对于后者情况IO调度将等待一个合适的时间(10ms)再无请求到来时进行下一个队列的服务,并且它会使读取请求优先执行,因为进程地址空间对应到物理空间的局部性,这个算法在避免“饿着”某一个IO请求的前提下保证了整体性能。

NOOP IO调度

这是一个针对非机械硬盘寻址机制出现的IO调度算法,比如固态硬盘,因为没有的机械动作的缘故,所以noop IO调度算法仅仅进行IO请求的合并而不进行排序,这种算法的效率简单且高效,但他依赖于物理设备。

查看和设置IO调度算法

IO调度算法的选择可以由内核启动参数传递设置,也可以通过/sys/block/device/queue/scheduler 获取当前IO调度算法和设置选择IO调度算法。除此之外还可以在用户空间优化IO的性能,这一部分就和应用的实现息息相关了,不过也常常就是三种方式,按路径,按inode,按物理块地址,因为常见文件系统会将同一路径的文件保存在物理地址相邻的地址中,Inode和物理块等都是一样的原理,就是将物理地址相邻的请求合并在一起交给内核,从而优化IO性能。

Linux的IO调度程序的更多相关文章

  1. Linux资源管理-IO优先级

    前一篇博客介绍了利用 cgroup 来控制进程的 CPU和内存使用情况, 这次补上使用 cgroup 来控制进程的IO优先级的方法. 前提条件 如果想控制进程的IO优先级, 需要内核的支持, 内核编译 ...

  2. Linux硬件IO的优化简介

    Linux硬件IO的优化简介 首先简单介绍下有哪些硬件设备如下(由于硬件种类厂家等各种因素我就不在此多做介绍有兴趣的可以自行学习): 1.CPU:中央处理器,是计算机运算控制的核心部件之一,相当于人的 ...

  3. linux标准io的copy

    ---恢复内容开始--- 1.linux标准io的copy #include<stdio.h> int main(int argc,char **argv) { if(argc<3) ...

  4. MySQL 调优基础(四) Linux 磁盘IO

    1. IO处理过程 磁盘IO经常会成为系统的一个瓶颈,特别是对于运行数据库的系统而言.数据从磁盘读取到内存,在到CPU缓存和寄存器,然后进行处理,最后写回磁盘,中间要经过很多的过程,下图是一个以wri ...

  5. Linux的io机制

    Linux的io机制 Buffered-IO 和Direct-IO Linux磁盘I/O分为Buffered IO和Direct IO,这两者有何区别呢? 对于Buffered IO: 当应用程序尝试 ...

  6. Linux Network IO Model、Socket IO Model - select、poll、epoll

    目录 . 引言 . IO机制简介 . 阻塞式IO模型(blocking IO model) . 非阻塞式IO模型(noblocking IO model) . IO复用式IO模型(IO multipl ...

  7. Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式

    Linux就这个范儿 第15章 七种武器  linux 同步IO: sync.fsync与fdatasync   Linux中的内存大页面huge page/large page  David Cut ...

  8. 转:Linux网络IO并行化技术概览

    转:http://codinginet.com/articles/view/201605-linux_net_parallel?simple=1&from=timeline&isapp ...

  9. Linux的IO调度

    Linux的IO调度 IO调度发生在Linux内核的IO调度层.这个层次是针对Linux的整体IO层次体系来说的.从read()或者write()系统调用的角度来说,Linux整体IO体系可以分为七层 ...

随机推荐

  1. HTML基础复习1

    网页:HTML(超文本标记语言) 网页分为静态网页和动态网页,区别:动态网页中可以加入脚本代码,还可以动态的引入数据库中的信息. HTML的结构 <html> <head>头信 ...

  2. 鸿蒙的多媒体及Menu组件及小程序的多媒体组件

    目录: js业务逻辑层 视图渲染层 css属性设置 效果图 微信小程序展示 内网穿透工具下载 我们在搭建一个小程序或者网站的时候,往往要加载很多的图片,音频和视频文件.如果都从服务器获取静态资源,这样 ...

  3. es_python_操作

    获取es索引 https://www.itranslater.com/qa/details/2583886977221264384

  4. Linux安装MYSQL并部署主从复制集群

    主节点部署 安装数据库 Ubuntu apt-get install mysql-server -y systemctl start mysql systemctl enabled mysql Cen ...

  5. linux静态库

    库文件可以理解为别人写好的现成的代码,但是看不见源码,只提供程序入口.库又分为动态库和静态库,静态库是在编译的时候将库编译进可执行程序中,运行时不再依赖库文件,而动态库是在运行时加载,运行时需要依赖库 ...

  6. windows桌面快速添加控制面板网络等图标

    默认安装后的windows系统只有回收站. rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,0

  7. from unittest import TestCase

    from unittest import TestCaseBigInteger/Big_Integer.py at master · YulitaGap/BigInteger https://gith ...

  8. 结合python版本安装python-devel gcc和g++的区别 安装前做yum搜索

    [test@ecs autocloudservices]# yum install python-develLoaded plugins: fastestmirrorLoading mirror sp ...

  9. JAD 反编译

    自动拆装箱 对于基本类型和包装类型之间的转换,通过xxxValue()和valueOf()两个方法完成自动拆装箱,使用jad进行反编译可以看到该过程: public class Demo { publ ...

  10. Codeforces 1220D 思维 数学 二分图基础

    原题链接 题意 我们有一个含多个正整数的集合B,然后我们将所有的整数,也就是Z集合内所有元素,都当做顶点 两个整数 \(i , j\) 能建立无向边,当且仅当 \(|i - j|\) 这个数属于B集合 ...