当前位置: 首页 > 科技观察

理解LinuxI-O调度器,优化系统性能

时间:2023-03-17 19:05:42 科技观察

前言LinuxI/O调度器是Linux内核不可或缺的一部分。用户可以通过调整这个调度器来优化系统性能。本文首先介绍了LinuxI/O调度器的结构,然后介绍了如何根据不同的内存设置LinuxI/O调度器来优化系统性能。LinuxI/O系统简介LinuxI/O调度器(LinuxI/OScheduler)是LinuxI/O系统的一个组件,介于通用块层和块设备驱动之间。如图1所示。图1LinuxI/O调度器介于通用块层和块设备驱动之间。当Linux内核组件要读写一些数据时,内核不会在请求一发出就立即执行,而是推迟执行。.当传输一个新的数据块时,内核需要检查它是否可以通过。LinuxIO调度器介于通用块层和块设备驱动之间,因此它接收来自通用块层的请求,尝试合并请求,并找到最合适的请求发送给块设备驱动。块设备驱动程序然后调用一个函数来响应请求。Linux整体的I/O系统可以分为七层,分别是:1.VFS虚拟文件系统:内核要处理多个文件系统,内核抽象出这个VFS,专门用来适应各种文件系统并与外界通信。提供统一的操作界面。2.磁盘缓存:磁盘缓存是一种软件机制,将磁盘上的一些数据保存在RAM中,使得对这部分数据的访问响应更快。Linux中的磁盘缓存分为三种:Dentry缓存、Page缓存、Buffer缓存。3、映射层:内核从块设备中读取数据,因此内核必须确定数据在物理设备上的位置,这是由映射层(MappingLayer)完成的。4、通用块层:由于大部分I/O操作都与块设备打交道,Linux提供了一个类似于vfs层的块设备操作抽象层。下层连接各种不同属性的块设备,向上层提供统一的BlockIO请求标准。5、I/O调度层:大部分块设备都是磁盘设备,因此需要根据这类设备的特点和应用特点设置一些不同的调度器。6、块设备驱动:块设备驱动提供了高级的设备操作接口。7、物理硬盘:这一层是具体的物理设备。5种LinuxI/O调度器Linux从2.4内核开始支持I/O调度器,目前有5种:Linux2.4内核的LinusElevator、Linux2.6内核的Deadline、Anticipatory、CFQ和Noop,其中自Linux2.6.33以来,Anticipatory已被删除。目前,主流的Linux发行版使用三种I/O调度器:Deadline、CFQ和Noop。下面依次简单介绍一下:1LinusElevator是2.4内核中的第一个I/O调度器。它的主要作用是为每个设备维护一个查询请求,当内核收到新的请求时,如果能合并就合并。如果不能合并,则尝试排序。如果既不能合并也不能插入到合适的位置,则将其放在请求队列的末尾。2AnticipatoryAnticipatory的中文意思是“预期的,预期的”。顾名思义,当一个I/O发生时,如果另一个进程请求一个I/O操作,会产生一个默认的6毫秒的猜测时间来猜测下一个进程请求。I/O的用途。I/O调度器优化读操作的服务时间,在提供一个I/O的同时等待一小段时间,以便进程可以提交另一个I/O。Anticipatory算法从Linux2.6.33开始被删除,因为Anticipatory的效果也可以通过CFQ的配置来实现。3DeadLineDeadline翻译成中文是一个截止时间调度器,是对LinusElevator的改进,可以防止一些请求被处理的时间过长。此外,可以区别对待读操作和写操作。DEADLINE还分别为读取I/O和写入I/O提供了FIFO队列。Deadline的工作流程如图2所示。图2Deadline工作流程4CFQCFQ全称CompletelyFairScheduler,中文名称为CompletelyFairScheduler。它是很多Linux发行版的默认调度器,CFQ是内核默认选择的I/O调度器。它将进程提交的同步请求放入多个进程队列中,然后为每个队列分配时间片访问磁盘。通用服务器的最佳选择,CFQ平均分配对I/O带宽的访问。CFQ为每个进程和线程创建一个单独的队列来管理进程产生的请求,从而保证每个进程都能很好地分配I/O带宽,I/O调度器一次执行一个队列。来自进程的4个请求。该算法的特点是按照I/O请求的地址排序,而不是按照先来后到的顺序响应。简单的说就是给所有的同步进程分配时间片,然后排队访问磁盘。CFQ的工作流程如图3所示。图3CFQ工作流程5NOOPNOOP全称NoOperation,中文名称为elevatorscheduler。该算法实现了最简单的FIFO队列,所有的I/O请求大致按照先到先得的顺序进行操作。NOOP实现了一个简单的FIFO队列,它像电梯工作方式一样组织I/O请求。它是Linux内核中基于先进先出(FIFO)队列概念的最简单的I/O调度程序。此调度程序最适用于固态驱动器。I/O调度器的选择目前,主流的Linux发行版使用三种I/O调度器:DeadLine、CFQ和NOOP。一般来说,Deadline适用于大部分环境,尤其是写入比较多的文件服务器。从原理上看,DeadLine是一种基于提高机械硬盘吞吐量的调度算法。它试图确保在达到截止日期时安排I/O请求。非常适合业务比较单一,I/O压力大的业务。如Web服务器、数据库应用等。CFQ为所有进程分配相同的带宽,适用于进程数较多的多用户系统。CFQ是一种比较通用的调度算法。它是一种以进程为出发点的调度算法,尽可能保证每个人都公平,为所有进程分配相同数量的带宽,适用于桌面多任务和多媒体应用。NOOP是闪存设备和嵌入式系统的最佳选择。对于SSD,使用NOOP是最好的,其次是DeadLine,CFQ效率最低。查看Linux系统的I/O调度器查看Linux系统的I/O调度器一般分为两部分,一是查看Linux系统整体使用的I/O调度器,二是查看Linux系统使用的I/O调度器查看某个磁盘设备使用的I/O调度程序。查看当前系统支持的I/O调度器,使用以下命令:#dmesg|grep-ischeduler[1.508820]ioschedulernoopregistered[1.508827]ioschedulerdeadlineregistered[1.508850]ioschedulercfqregistered(default)显示cfq是当前的I/O调度器。查看某个硬盘的I/O调度器,使用如下命令:#cat/sys/block/sda/queue/schedulernoopdeadline[cfq]可以看出当前使用的调度器是cfq,也就是括号里的那个。修改Linux系统的I/O调度器修改Linux系统的I/O调度器有三种方法,分别是使用shell命令、使用grubby命令或修改grub配置文件。下面依次介绍:1、在Linux下使用shell命令改变I/O调度器非常简单。不需要更新内核,可以使用shell命令修改:#echonoop>/sys/block/sdb/queue/scheduler清单3中的命令将noop设置为磁盘I/O调度程序,您可以随时更改它而无需重新启动计算机。2.永久修改默认的I/O调度器。使用shell命令修改I/O调度程序。这只是一个临时修改。系统重启后,修改后的调度器将失效。要修改默认调度程序,有两种方法。grubby命令或直接编辑grub配置文件。以使用grubby命令为例,需要将I/O调度器从cfq调整为DeadLine,命令如下:#grubby--grub--update-kernel=ALL--args="elevator=deadline"通过设置内核加载参数,这样当机器重启时,系统自动将所有设备的I/O调度器改为DeadLine。3.使用编辑器修改配置文件。您也可以直接编辑grub配置文件。通过修改grub配置文件,系统自动将所有设备的I/O调度器改为cfq。运行过程如下:#vicat/etc/default/grub#修改第五行,在行尾添加#elevator=cfq并保存文件,重新编译配置文件,#grub2-mkconfig-o/boot/grub2/grub.cfg重启电脑系统。总结LinuxI/O调度程序是Linux内核不可或缺的一部分。用户可以根据不同的内存设置LinuxI/O调度器来优化系统性能。一般来说,NOOP调度器最适合固态硬盘,DeadLine调度器适合写入比较多的文件服务器,比如Web服务器、数据库应用等,CFQ调度器适合桌面多任务和媒体应用.