设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 手机 数据 公司
当前位置: 首页 > 服务器 > 安全 > 正文

如何提高Linux下块设备IO的整体性能?(2)

发布时间:2021-01-04 22:01 所属栏目:53 来源:网络整理
导读:带宽就是以时间为单位的读写数据量,比如,100Mbyte/s.而IOPS是以时间为单位的读写次数.在不同的读写情境下,这两个单位的表现可能不一样,但是可以确定的是,两个单位的任何一个达到了性能上限,都会成为IO的瓶颈. 从机

带宽就是以时间为单位的读写数据量,比如,100Mbyte/s.而IOPS是以时间为单位的读写次数.在不同的读写情境下,这两个单位的表现可能不一样,但是可以确定的是,两个单位的任何一个达到了性能上限,都会成为IO的瓶颈.

从机械硬盘的结构考虑,如果读写是顺序读写,那么IO的表现是可以通过比较少的IOPS达到较大的带宽,因为可以合并很多IO,也可以通过预读等方式加速数据读取效率.

当IO的表现是偏向于随机读写的时候,那么IOPS就会变得更大,IO的请求的合并可能性下降,当每次io请求数据越少的时候,带宽表现就会越低.

从这里我们可以理解,针对进程的IO资源的主要表现形式有两个:进程在单位时间内提交的IO请求个数和进程占用IO的带宽.

其实无论哪个,都是跟进程分配的IO处理时间长度紧密相关的.

有时业务可以在较少IOPS的情况下占用较大带宽,另外一些则可能在较大IOPS的情况下占用较少带宽,所以对进程占用IO的时间进行调度才是相对最公平的.

即,我不管你是IOPS高还是带宽占用高,到了时间咱就换下一个进程处理,你爱咋样咋样.

所以,cfq就是试图给所有进程分配等同的块设备使用的时间片,进程在时间片内,可以将产生的IO请求提交给块设备进行处理,时间片结束,进程的请求将排进它自己的队列,等待下次调度的时候进行处理.这就是cfq的基本原理.

当然,现实生活中不可能有真正的“公平”,常见的应用场景下,我们很肯能需要人为的对进程的IO占用进行人为指定优先级,这就像对进程的CPU占用设置优先级的概念一样.

所以,除了针对时间片进行公平队列调度外,cfq还提供了优先级支持.每个进程都可以设置一个IO优先级,cfq会根据这个优先级的设置情况作为调度时的重要参考因素.

优先级首先分成三大类:RT、BE、IDLE,它们分别是实时(Real Time)、最佳效果(Best Try)和闲置(Idle)三个类别,对每个类别的IO,cfq都使用不同的策略进行处理.另外,RT和BE类别中,分别又再划分了8个子优先级实现更细节的QOS需求,而IDLE只有一个子优先级.

另外,我们都知道内核默认对存储的读写都是经过缓存(buffer/cache)的,在这种情况下,cfq是无法区分当前处理的请求是来自哪一个进程的.

只有在进程使用同步方式(sync read或者sync wirte)或者直接IO(Direct IO)方式进行读写的时候,cfq才能区分出IO请求来自哪个进程.

所以,除了针对每个进程实现的IO队列以外,还实现了一个公共的队列用来处理异步请求.

当前内核已经实现了针对IO资源的cgroup资源隔离,所以在以上体系的基础上,cfq也实现了针对cgroup的调度支持.

总的来说,cfq用了一系列的数据结构实现了以上所有复杂功能的支持,大家可以通过源代码看到其相关实现,文件在源代码目录下的block/cfq-iosched.c.

1.1 cfq设计原理

在此,我们对整体数据结构做一个简要描述:首先,cfq通过一个叫做cfq_data的数据结构维护了整个调度器流程.在一个支持了cgroup功能的cfq中,全部进程被分成了若干个contral group进行管理.

每个cgroup在cfq中都有一个cfq_group的结构进行描述,所有的cgroup都被作为一个调度对象放进一个红黑树中,并以vdisktime为key进行排序.

vdisktime这个时间纪录的是当前cgroup所占用的io时间,每次对cgroup进行调度时,总是通过红黑树选择当前vdisktime时间最少的cgroup进行处理,以保证所有cgroups之间的IO资源占用“公平”.

当然我们知道,cgroup是可以对blkio进行资源比例分配的,其作用原理就是,分配比例大的cgroup占用vdisktime时间增长较慢,分配比例小的vdisktime时间增长较快,快慢与分配比例成正比.

这样就做到了不同的cgroup分配的IO比例不一样,并且在cfq的角度看来依然是“公平“的.

选择好了需要处理的cgroup(cfq_group)之后,调度器需要决策选择下一步的service_tree.

service_tree这个数据结构对应的都是一系列的红黑树,主要目的是用来实现请求优先级分类的,就是RT、BE、IDLE的分类.每一个cfq_group都维护了7个service_trees,其定义如下:

其中service_tree_idle就是用来给IDLE类型的请求进行排队用的红黑树.

而上面二维数组,首先第一个维度针对RT和BE分别各实现了一个数组,每一个数组中都维护了三个红黑树,分别对应三种不同子类型的请求,分别是:SYNC、SYNC_NOIDLE以及ASYNC.

我们可以认为SYNC相当于SYNC_IDLE并与SYNC_NOIDLE对应.idling是cfq在设计上为了尽量合并连续的IO请求以达到提高吞吐量的目的而加入的机制,我们可以理解为是一种“空转”等待机制.

空转是指,当一个队列处理一个请求结束后,会在发生调度之前空等一小会时间,如果下一个请求到来,则可以减少磁头寻址,继续处理顺序的IO请求.

为了实现这个功能,cfq在service_tree这层数据结构这实现了SYNC队列,如果请求是同步顺序请求,就入队这个service tree,如果请求是同步随机请求,则入队SYNC_NOIDLE队列,以判断下一个请求是否是顺序请求.

所有的异步写操作请求将入队ASYNC的service tree,并且针对这个队列没有空转等待机制.

此外,cfq还对SSD这样的硬盘有特殊调整,当cfq发现存储设备是一个ssd硬盘这样的队列深度更大的设备时,所有针对单独队列的空转都将不生效,所有的IO请求都将入队SYNC_NOIDLE这个service tree.

每一个service tree都对应了若干个cfq_queue队列,每个cfq_queue队列对应一个进程,这个我们后续再详细说明.

cfq_group还维护了一个在cgroup内部所有进程公用的异步IO请求队列,其结构如下:

异步请求也分成了RT、BE、IDLE这三类进行处理,每一类对应一个cfq_queue进行排队.

BE和RT也实现了优先级的支持,每一个类型有IOPRIO_BE_NR这么多个优先级,这个值定义为8,数组下标为0-7.

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读