Linux中常见IO调度器

Linux中常见IO调度器,第1张

对于磁盘I/O,Linux提供了cfq, deadline和noop三种调度策略

考虑到硬件配置、实际应用场景(读写比例、顺序还是随机读写)的差异,上面的简单解释对于实际选择没有太大帮助,实际该选择哪个基本还是要实测来验证。不过下面几条说明供参考:

NOOP全称No Operation,中文名称电梯式调度器,该算法实现了最简单的FIFO队列,所有I/O请求大致按照先来后到的顺序进行 *** 作。NOOP实现了一个简单的FIFO队列,它像电梯的工作方式一样对I/O请求进行组织。它是基于先入先出(FIFO)队列概念的 Linux 内核里最简单的I/O 调度器。此调度程序最适合于固态硬盘。

Deadline翻译成中文是截止时间调度器,是对Linus Elevator的一种改进,它避免有些请求太长时间不能被处理。另外可以区分对待读 *** 作和写 *** 作。DEADLINE额外分别为读I/O和写I/O提供了FIFO队列。

Deadline对读写request进行了分类管理,并且在调度处理的过程中读请求具有较高优先级。这主要是因为读请求往往是同步 *** 作,对延迟时间比较敏感,而写 *** 作往往是异步 *** 作,可以尽可能的将相邻访问地址的请求进行合并,但是,合并的效率越高,延迟时间会越长。因此,为了区别对待读写请求类型,deadline采用两条链表对读写请求进行分类管理。但是,引入分类管理之后,在读优先的情况下,写请求如果长时间得到不到调度,会出现饿死的情况,因此,deadline算法考虑了写饿死的情况,从而保证在读优先调度的情况下,写请求不会被饿死。

总体来讲,deadline算法对request进行了优先权控制调度,主要表现在如下几个方面:

CFQ全称Completely Fair Scheduler ,中文名称完全公平调度器,它是现在许多 Linux 发行版的默认调度器,CFQ是内核默认选择的I/O调度器。它将由进程提交的同步请求放到多个进程队列中,然后为每个队列分配时间片以访问磁盘。 对于通用的服务器是最好的选择,CFQ均匀地分布对I/O带宽的访问 。CFQ为每个进程和线程,单独创建一个队列来管理该进程所产生的请求,以此来保证每个进程都能被很好的分配到I/O带宽,I/O调度器每次执行一个进程的4次请求。该算法的特点是按照I/O请求的地址进行排序,而不是按照先来后到的顺序来进行响应。简单来说就是给所有同步进程分配时间片,然后才排队访问磁盘。

多队列无 *** 作I / O调度程序。不对请求进行重新排序,最小的开销。NVME等快速随机I / O设备的理想选择。

这是对最后期限I / O调度程序的改编,但设计用于 多队列设备。一个出色的多面手,CPU开销相当低。

前言:本文主要讲解Linux IO调度层的三种模式:cfp、deadline和noop,并给出各自的优化和适用场景建议。IO调度发生在Linux内核的IO调度层。这个层次是针对Linux的整体IO层次体系来说的。从read()或者write()系统调用的角度来说,Linux整体IO体系可以分为七层,它们分别是:

VFS层: 虚拟文件系统层。由于内核要跟多种文件系统打交道,而每一种文件系统所实现的数据结构和相关方法都可能不尽相同,所以,内核抽象了这一层,专门用来适配各种文件系统,并对外提供统一 *** 作接口。

文件系统层: 不同的文件系统实现自己的 *** 作过程,提供自己特有的特征,具体不多说了,大家愿意的话自己去看代码即可。

页缓存层: 负责真对page的缓存。

通用块层: 由于绝大多数情况的io *** 作是跟块设备打交道,所以Linux在此提供了一个类似vfs层的块设备 *** 作抽象层。下层对接各种不同属性的块设备,对上提供统一的Block IO请求标准。

IO调度层 :因为绝大多数的块设备都是类似磁盘这样的设备,所以有必要根据这类设备的特点以及应用的不同特点来设置一些不同的调度算法和队列。以便在不同的应用环境下有针对性的提高磁盘的读写效率,这里就是大名鼎鼎的Linux电梯所起作用的地方。针对机械硬盘的各种调度方法就是在这实现的。

块设备驱动层: 驱动层对外提供相对比较高级的设备 *** 作接口,往往是C语言的,而下层对接设备本身的 *** 作方法和规范。

块设备层: 这层就是具体的物理设备了,定义了各种真对设备 *** 作方法和规范。

有一个已经整理好的[Linux IO结构图],非常经典,一图胜千言:

1.Deadline scheduler Deadline scheduler 用 deadline 算法保证对于既定的 IO 请求以最小的延迟时间,从这一点理解,对于 DSS 应用应该会是很适合的。

2.Anticipatory scheduler(as) 曾经一度是 Linux 2.6 Kernel 的 IO scheduler 。Anticipatory 的中文含义是”预料的, 预想的”, 这个词的确揭示了这个算法的特点,简单的说,有个 IO 发生的时候,如果又有进程请求 IO *** 作,则将产生一个默认的 6 毫秒猜测时间,猜测下一个 进程请求 IO 是要干什么的。这对于随即读取会造成比较大的延时,对数据库应用很糟糕,而对于 Web Server 等则会表现的不错。这个算法也可以简单理解为面向低速磁盘的,因为那个”猜测”实际上的目的是为了减少磁头移动时间。

3.Completely Fair Queuing 虽然这世界上没有完全公平的事情,但是并不妨碍开源爱好者们设计一个完全公平的 IO 调度算法。Completely Fair Queuing (cfq, 完全公平队列) 在 2.6.18 取代了 Anticipatory scheduler 成为 Linux Kernel 默认的 IO scheduler 。cfq 对每个进程维护一个 IO 队列,各个进程发来的 IO 请求会被 cfq 以轮循方式处理。也就是对每一个 IO 请求都是公平的。这使得 cfq 很适合离散读的应用(eg: OLTP DB)。我所知道的企业级 Linux 发行版中,SuSE Linux 好像是最先默认用 cfq 的.

4.NOOP Noop 对于 IO 不那么 *** 心,对所有的 IO请求都用 FIFO 队列形式处理,默认认为 IO 不会存在性能问题。这也使得 CPU 也不用那么 *** 心。当然,对于复杂一点的应用类型,使用这个调度器,用户自己就会非常 *** 心。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/7258712.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-03
下一篇 2023-04-03

发表评论

登录后才能评论

评论列表(0条)

保存