IO调度器详解

news2024/10/6 20:38:35

一、调度器演进

1.1 什么是IO调度器?

       5de7233f700b3071c68ede9d9d3a5c75.png

传统的磁盘因为有磁头,磁头移动有开销。最早的调度器会对访问磁盘的IO做基于磁盘访问位置的排序和合并, 让磁头以最少的移动来完成最大的IO量, 以提升系统IO带宽。

b854585bca3e9b53088fea4694712c73.png       af51cb51bc1c481c526b4a0e3f8b59aa.png

现在的SSD, 物理上已没有磁头的概念, 访问的位置也是LBA(Logical block address), 器件内部负责找到LBA到物理位置的映射关系。排序就没有太大作用, 随机访问的速度也接近顺序读写。IO调度主要是以服务应用场景为主(读优先,VIP线程优先,时间片/带宽公平调度等) 。    

IO scheduler处于内核IO栈 中block layer的一部分,主要作用就是对IO 进行qos, 根据不同的qos目标(延迟、公平、带宽、功耗等)有各种各样的调度器:历史到现在mainline出现过(红色是现存的):noop(只做简单的merge )/deadline(排序,读写区分对待,延迟控制)/cfs(时间片公平)/mq-deadline/bfq(带宽公平)/kyber(不同的IO类型 q不同的延迟)    

     
未进mainline的调度器:

SIO(不合并IO)、VR(翻转磁头惩罚机制)、Row(read over write)、Zen(不合并也不排序,仅有超期处理) 、Maple(不合并不排序,亮屏和灭屏策略不一样) 、FIO(基于IOPS指标 进程公平)等。

这些调度器随着发展, 目前只有右图这样子:

030bda4168b0401cceece5034206a633.png

 现在看看这些调度器的策略有什么不同:    

1.2 kernel 6.1 社区调度器

Kyber调度器

2017年引入,2018后就不怎么修改(目前为止,没有支持io priority /blk cg)。核心思想, 就是把IO分成不同的类型(读、写、擦除、其他),  每个类型的队列单独控制延时, q的是不同的延迟, 所有策略围绕这个目标展开。

22f0c411ea856ad2e6978c9dd253471b.png     

cde0e333667bc7a2c0f7d19642e72b30.png

默认情况下延迟控制如上

         
1.3 MQ-DEADILINE调度器    

作为deadline的mult queue版本。deadline在内核2.5时代已经存在。         
核心思想没有变化:     

1. IO进入调度器会被同时加入 读写rb tree 和fifo 队列中, 按访问sector排序。         
2. 如果有超期的IO ,先发送超期的IO, 无超期的IO 按优先级发送IO, 同优先级读写非严格按照2:1 dispatch,  发送IO时 按各自rb tree 发送(sector 增长方向)。         
3. 读和写的超期时间不一样。         
1ceb374466dc5e24fa5ce4ebcb24fe78.png          
4. 预留了1/4 req给同步IO(除去write)。

7b6ba24cd6d1e9b8d0efef90cf9a7373.png          
5. dispatch先检查超期req (读和写超期时间不一样),  无超期 再按读写2:1的比例下发IO。

6. linux-5.14开始支持ioclass/ionice。

7. 不支持blk cgroup

1.4 BFQ调度器    

改自CFQ,BFQ 是 带宽公平的调度器, 支持cgroup.  从4.12版本开始支持, 设计原则想兼顾带宽和响应。实际上由于算法复杂,最低lat会其他调度器多数倍。         

核心特性:

1. “budget fair”策略:每个线程公平的分配sector数进行IO, 因交互式进程只需少量的budget, 交互式进程得以快速响应。

2. 优先级支持:进程bfq weight越大(新进程权重临时提升),budget增长越慢(意味着调度更频繁)。         
3. 调度效率。引入idle_time,做完一个thread的IO后 。为了不让这个APP后续IO重新排队(也为了新的APP得到比较好速度), 会idle一定时间再切换下一个线程。

二、kernel6.1的elv(bfq/kyber/mq-deadline)

elv 实现其实是一套call back 嵌入在block layer, 搞清楚这些call back就可以看出不同elv的核心思想。

           149e8c512ecfc7c8eba6c28e008731f7.png

        cff8037de95c1201e4cd0691ef92a995.png

 一笔IO 要在elv中经过:allow_megre->bio_merge->requset_merge->request_merged->limit_depth->prepare_request->insert_request->has_work->dispatch_request->completed_request->finish_request 才可以一笔IO。

在block layer, 什么时候IO 会进入调度器?

实际上有很多入口,整体上submit_bio是从fs下来的普通IO(常规的文件访问),其他一些入口主要给一些特别的IO使用,比如ioctl(查询器件状态等), flush等。这些特别的IO 虽然会经历这个flow,但通常by pass调度器。         

        d53c3c7a430ee0c7860adb8947ee39e0.png

insert req就是把req挂入到elv的队列中(每种elv的队列实现方式通常都不一样), dispatch的线程不一定是IO的发起者, 有两个case:          
    1.  IO业务发起者直接下发到设备驱动,(需要同步IO + 设备ready)          
    2.  经过run_work异步线程转发(异步IO,或同步IO发起时,设备没ready)    

        dff2dcd6f7ccc51b5691006663940b38.png          
2.1 Kyber调度器

6e5583c58ace9ab1a9705941543777f0.png

Kyber引入调度域的概念:给IO划分了4个调度域,每个域都有一个bitmap, 表示该域req 资源占用情况。

d8123706998bfaf951e32e332a05060a.png

每个调度域的深度不一样, 即可用req数量不一样。插入IO实际上就是插入到这个阈所属的队列上。

4a854dd896653624c6d3f97d08360eeb.png

每个调度域batch size不一样,即每次一个调度域单次最多dispatch处理batch_size个reqs。    

b3e2138230e70fead65e783e914e2cc8.png

异步IO 占比75%, 即总是预留25% 的req给同步IO。

123a57cce1e8ceb2e5241285b064b2ae.png

不同类型IO延迟控制不一样。

2759b06cb49923906f65f3f37f29c7dd.png

Kyber insert req

可以看到就是根据IO的类型, 比如是读 还是写 或擦除操作,把IO加入到不同阈的队列当中。    

08667c5aab9afc7241621f4efeac3dd1.png

Kyber dispatch

Dispatch则是根据不同阈IO的质量(kyber以IO花费的平均时间作为指标,),选择合适的队列进行dispatch

                       
 选择一个domain 最多发送batch个req.

3047b07b78e3696a3023f192b7385318.png

找到队列中的req进行dispatch 

 b6e94d466a0a23d985a41b83af9b6f70.png

kyber在选择domain时,要根据IO的质量(IO花费时间), 下面说说质量是如何算的:         
Kyber 时延计算    

04c65aa527f312874d3d3507c0a48797.png

KYBER_IO_LATENCY: rq执行的时间(类似D2C)

KYBER_TOTAL_LATENCY:rq从申请出来到执行完的时间(类似G2C)

13bf64e4e3f43ec01ae0fab362054012.png

 简单的可以理解为,kyber在IO完成的时候,根据IO的花费时间,在bucket中选择合适的位置进行计数。 比如1 为延迟10ms, 如果这笔IO完成在3/4 * 10ms -> 10ms之间, 则在1的bucket里+1;

 这样定期查看下某个类型的buckets 比如READ domian, 就可以看到99% READ 延迟在哪个区段。如果落在1之内认为IO是好的, 如果都大于1 认为IO是坏的。

         
如果IO是坏的,那以后就多发这个类型的IO,少发其他类型的IO, 这类型IO的延迟就可能会好转。Kyber就是通过调整发不同类型IO的数量来完成IO的时延控制。     

   
看下他是如何调整分发数量的:    

  Kyber 根据时延调整 队列深度

d18b52e6e55fe8c736b096e7e5375146.png 

good_buckets即上述所指1的位置, 计算99%的IO和90%的IO在什么区段,来调整队列的depth

e9f2ad93e3caa45505feaa074a0c00be.png

如果比较差,就增加对应队列一倍的depth. 如果很好就缩减到3/4的深度。

延迟的计算如下    

b5430441dd2bd229528b3a93316a600d.png

Kyber小结

4e833e0f9ec0995385f443b7e59be419.png

2.2  mq_deadline调度器   

从数据结构来看, 他有优先级的概念,并且有所谓的方向(读or写)

struct deadline_data *dd = q->elevator->elevator_data;

19d219da63fc4e35330e89397b69f0f0.png

d45485443f669f0864c28855f5a636ca.png

同时也有expire的概念。

43419ee392697f66dfee775f764a074b.png

从数据上看, 总结为:

mq_deadline 三个优先级,两种队列,两种IO类型

         
mq_deadline 插入req,  就是根据IO是读写, 把IO插入到对应优先级的双重队列里:即插入到fifo队列 和sort队列(根据IO访问磁盘的位置)中    

mq_deadline insert req

63daeaacb9e4fa7c4144dbf90449a456.png

分发条件也简单, 统计进入elv的总数,有IO 就可以发

mq_deadline has work

f5658aa8627c3ea1334bf0715ed92858.png

所谓的deadline,即IO进入elv开始到dispatch有一个deadline.          
因此在发送顺序上, 要先找超期的req进行发送, 如果没有超期的req,则按优先级进行发送。    

mq_deadline dispatch

6439d1f807d28b2d37bbdc81f222ed03.png

mq_deadline 小结

IO 按磁盘位置在对应优先级的sort tree上排序,发送时先发超期IO,再按优先级发送。(实际上还有write_starved的概念,deadline倾向于发读IO,为了防止写饿死, 会发write_starved次读,才会发一次写)

4982ed565d7267e16318c735c23ad86a.png

         
2.3  BFQ(Budget Fair Queueing)调度器   

21f3853262c21823da887c2eb6643428.png

BFQ的核心思想,就是by thread的发送IO,有点CPU 调度的味道, 每次能发的最大IO量即所谓的Budget。BFQ想保证不同的thread在IO量上是“公平的”。

整体思想就是每个thread在IO上也有一个vtime, 每次总是选vtime小的thread进行发送IO。对于IO的vtime的增长, 在BFQ上是根据这个线程发过的IO量*系数来决定的, 每次能发的最大虚拟IO量 即所谓的buget。

而这里的系数,则比较复杂,BFQ会根据不同类型的IO负载 ,给thread打上标签,比如是交互式线程 还是IO消耗性线程,甚至是刚起来的新线程,依赖多个维度权衡去动态调整系数。从而保证整个系统有比较好的IO响应且比较好的带宽。         

6037acef08cab03c7a48cf605340e697.png

由于BFQ的细节流程比较复杂,这里列出其flow:

 BFQ insert req

8154a93a9760753cbd025da7a602079a.png    

BFQ dispatch req

b989328bda5153966f026e54bb989ccc.png

BFQ dispatch req

总是选vtime最小的进行发送

e4dfd219a35417931cff262fde1f887c.png          

三、cgroup/ionice          


有些调度器是支持IO优先级和cgroup的,业务方时间上可以根据这两个机制 来调整自己IO的质量。

usage: ionice [-t] [-c CLASS] [-n LEVEL] [COMMAND...|-p PID]

deadline idle/RT的带宽差距

7f7efb0190149b6c4bca67c98206c3d8.png

d6143e3a965582778563efb4aefbe25f.png

两个cgroup: target为idle, load为RT

ae790977c2f9b92b9719a323910f1109.png

cgroup

dc247e0f9383b6644b1266f9dbc10039.png6fec2c55dbcbfb65ce4c0371d4759278.pngexample:

v1:echo 100 > /dev/blkio/target/blkio.bfq.weight          
v2:echo "8:16 rbps=2097152 wiops=120" > io.max    

eba59a047475cb8938d28c374fae926f.png

19cd3551119df951bfa29b6b83a860d2.png

四、other vendor elv

https://github.com/codediablos/io-scheduler/blob/master/vr-iosched.c

https://github.com/codediablos/io-scheduler/blob/master/sio-iosched.c

https://github.com/Pzqqt/android_kernel_xiaomi_whyred/blob/5e5993a2fa5c19d29fe63ee628299ff97ba910fd/block/fiops-iosched.c

https://github.com/codediablos/io-scheduler/blob/master/row-iosched.c

https://github.com/Pzqqt/android_kernel_xiaomi_whyred/blob/5e5993a2fa5c19d29fe63ee628299ff97ba910fd/block/maple-iosched.c#L4

https://github.com/codediablos/io-scheduler/blob/master/zen-iosched.c

参考资料:

1.https://elixir.bootlin.com/linux/v6.1.80/source/Documentation/block    

2.BFQ:

https://blog.csdn.net/hu1610552336/article/details/125862606    

Android分区挂载原理介绍(上)

Android分区挂载原理介绍(下)

Perfetto数据流架构故障分析:带你研究 trace 为何丢失

603f853616b56e0beb43ead4095b16c6.gif

长按关注内核工匠微信

Linux内核黑科技| 技术文章| 精选教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1502171.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

201909青少年软件编程(Scratch)等级考试试卷(三级)

青少年软件编程(Scratch)等级考试试卷(三级)2019年9月 第1题:【 单选题】 执行下面的脚本后,变量“分数”的值是多少?() A:5 B:6 C:10 D:25 【正确答案】: C 【试题…

NASA数据集——GOES-16卫星的高级图像和地球观测数据

简介 GHRSST NOAA/STAR GOES-16 ABI L2P America Region SST v2.70 dataset in GDS2 ABI_G16-STAR-L2P-v2.70是美国国家航空航天局(NASA)的一种卫星数据处理产品。这个产品是由GOES-16(也称为GOES-East)卫星的先进基线/全球地球…

无法设置查询条件,应该如何解决?

使用易查分制作查询系统时,无法正常设置查询条件,应如何解决? 📌问题解决方法 01表格第一行是标题 如果上传的表格,第1行内容是标题而非表头,则易查分系统将无法识别查询条件,需要重新上传第1行…

Spring Cloud微服务在Windows本地开发时禁用Nacos注册中心注册

码到三十五 : 个人主页 心中有诗画,指尖舞代码,目光览世界,步履越千山,人间尽值得 ! 本文将介绍如何在Spring Cloud微服务架构中,实现在Windows本地开发环境下禁用服务自动注册到Nacos注册中心&#xff0…

有点NB的免费wordpress主题模板

一个不错的黄色模板,用WP免费主题模板搭建家政服务公司网站。 https://www.wpniu.com/themes/15.html

【npm】前端工程项目配置文件package.json详解

简言 详细介绍了package.json中每个字段的作用。 package.json 本文档将为您介绍 package.json 文件的所有要求。它必须是实际的 JSON,而不仅仅是 JavaScript 对象文字。 如果你要发布你的项目,这是一个特别重要的文件,其中name和version是…

智能音箱技术解析

目录 前言智能音箱执行步骤解析1.1 探测唤醒词或触发词1.2 语音识别1.3 意图识别1.4 执行指令 2 典型的智能音箱2.1 百度小度音响2.2 小米小爱同学2.3 苹果 HomePod 3 功能应用举例3.1 设置计时器3.2 播放音乐 结语 前言 智能音箱已经成为日常生活中不可或缺的一部分&#xff…

(七)数据库的安全性

7.1存取控制 7.1.1自主存取控制DAC 7.1.2强制存取控制MAC 7.2审计 其他安全性保护

【字符串】【分类讨论】【KMP】1163. 按字典序排在最后的子串

作者推荐 视频算法专题 本文涉及知识点 字符串 字典序 分类讨论 本题无法使用KMP,因为t1不段变化。 LeetCode1163. 按字典序排在最后的子串 给你一个字符串 s ,找出它的所有子串并按字典序排列,返回排在最后的那个子串。 示例 1&#xf…

关于华为昇腾(Ascend)AI芯片,CANN计算架构,MindSpore深度学习框架,MindStudio开发工具

1、华为昇腾生态 深度学习之前的配置都是:NVIDIA GPU / CPU CUDA Tensorflow/PyTorch 后来老美禁止 NVIDIA 卖GPU芯片给我们,于是国内企业开始发力CPU和GPU硬件,成果丰硕,虽然与NVIDIA顶级GPU还有一些差距,但是也不…

网络故障基本判断方法

1)电脑上使用winR键,打开运行窗口,输入CMD命令,点击回车键 2)在弹出的CMD运行窗口中输入ipconfig命令 通过该命令可以查看本机的IP地址,子网掩码和网关等信息。确认电脑中所有网卡配置是否正确。 3&…

有点炫酷有点diao的免费wordpress模板主题

这是一款经典的免费wordpress主题,被广泛应用于多个行业的网站。 https://www.wpniu.com/themes/189.html

【linux】04 :linix实用操作

1.常用快捷键 ctrlc表示强制停止。linux某些程序的运行,如果想强制停止,可以使用;命令输入错误,也可以通过ctrlc,退出当前输入,重新输入。 ctrld表示退出登录,比如退出root以回到普通用户,或者…

visual studio 将编译后的dll等文件自动复制到指定目录

编译后的文件dll等总要手动复制到指定目录下,为了解决这一繁琐的操作,可以直接设置在编译完成后,自动复制到目标目录 - 在解决方案资源管理器,选中项目右键-》选中属性-》在弹出的面板选择生成事件 - 在后期生成事件命令行里填写…

IOS降级后从高版本到低版本恢复备份

IOS降级后从高版本到低版本恢复备份 此方法只适用于小版本还原,比如17.4->17.3,未验证大版本恢复可行性手机型号:iphone 13pro 系统版本:17.4 降级版本:17.3.1 步骤 通过itunes或者MacOS系统下对当前版本进行备份…

React-useEffect

1.概念 说明:用于在React组件中创建不是由事件引起而是由渲染本身引起的操作,比如发送 A列AX请求,更改DOM等。 2.案例 // useEffect用于组件不是由事件引起的而是由渲染本身引起的操作,如ajax,更改Dom等。 import { useEffect,…

【MapReduce】03.MapReduce框架原理

目录 1.InputFormat数据输入 1.1.切片与MapTask并行度决定机制 1.2.Job提交流程源码和切片源码 1.3.FileInputFormat切片机制 1.4.TextInputFormat 1.5.CombineTextInputFormat切片机制 1.6.CombineTextInputFormat 1.InputFormat数据输入 1.1.切片与MapTask并行度决定…

小白跟做江科大51单片机之AD/DA

1.看原理图找接口 2.看时序图编写读取数据代码 XPT2046.c代码 #include <REGX52.H> //引脚定义 sbit XPY2046_DINP3^4; sbit XPY2046_CSP3^5; sbit XPY2046_DCLKP3^6; sbit XPY2046_DOUTP3^7; unsigned int XPT2046_ReadAD(unsigned char Command) { unsigned char …

基于SSM的党务政务服务热线平台(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的党务政务服务热线平台&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spri…

Windows®、Linux® 和 UNIX® 系统都适用的远程桌面工具 OpenText ETX

Windows、Linux 和 UNIX 系统都适用的远程桌面工具 OpenText ETX 为 Windows、Linux 和 UNIX 实施精益、经济高效的虚拟化&#xff1b;提供完整的远程 Windows 可用性&#xff1b;以类似本地的性能远程工作&#xff1b;安全地保护系统和知识产权&#xff08;IP&#xff09;&am…