想象你走进一家生意火爆的餐厅,后厨只有一位厨师,一次只能做一道菜。客人点单后,服务员把菜单贴在墙上。后厨按什么顺序做菜,直接决定了每位客人的等待时间和餐厅的整体口碑——这就是I/O调度的本质。 在计算机世界里,磁盘就是这个“厨师”,一次只能服务一个I/O请求;操作系统里的I/O调度器则是那位决定“先做哪道菜”的前台经理。不同的调度算法,对应着不同的经营策略:有的追求公平、有的追求效率、有的保证期限。 Linux主流调度算法有CFQ、Deadline、NOOP和BFQ四种。CFQ像一位“轮流叫号”的公平经理,让每位进程都得到服务;Deadline像一位“急单优先”的时限经理,快超时的请求立刻插队;NOOP像一位“先来后到”的呆板经理;而BFQ则像一位“看人下菜碟”的精明经理,为不同进程分配不同权重。选择哪种算法,就像选择哪种经营风格,完全取决于你的“餐厅”开在什么样的街区。
理解I/O调度算法是优化数据库性能、设计高并发系统的基本功。对AI从业者而言,训练数据的读取、模型文件的加载、checkpoint的写入都依赖I/O性能,选对调度器能让你的Pipeline跑得更快。
可视化演示
I/O调度算法决定磁盘请求的执行顺序,CFQ、Deadline、NOOP和BFQ是Linux主流策略。本文讲解... 切换模式查看不同维度。
本节配有交互动效(进入视口后自动加载,约 3KB)。
I/O调度问:核心原理 动态展示关键流程与数据流动 交互控件调节参数实时渲染 f(x) = transform(x) 核心概念的可视化呈现
调度器概述
想象你是这家“磁盘餐厅”的老板,后厨只有一位厨师——磁盘的磁头,一次只能做一道菜。客人们(进程)不断递来点单(I/O请求),如果没有一个安排顺序的人,厨房就会立刻乱成一锅粥。I/O调度器就是那位站在出菜口、决定“下一道菜先做谁”的前台经理,它的一举一动直接决定每位客人的等餐时间。
在Linux系统中,I/O调度器位于文件系统和块设备驱动之间。当进程发起read()或write()系统调用时,请求并不会直接到达磁盘,而是先进入调度器的请求队列。调度器的任务就是决定这些请求以什么顺序离开队列、交给磁盘执行。这个看似简单的“排序”问题,背后却牵涉到磁盘的物理特性和多进程的公平之争。
磁盘和内存不同,它的服务时间由三部分组成:磁头移动到目标磁道所需的时间(寻道时间)、盘片旋转到目标扇区所需的时间(旋转延迟)、以及实际读写数据的时间(传输时间)。其中寻道时间往往占到总延迟的80%以上,是调度算法最想优化的对象。调度的本质,就是在“减少寻道开销”和“保证进程公平”之间做权衡——这也是前台经理最头疼的事。
所以,一个好的前台经理不会简单地按点单先后来出菜,而是要全局思考:哪些菜品的食材在同一个灶台(磁道)附近,可以顺路一起做?哪些客人的等待时间已经太长需要优先安抚?这些考量,正是不同调度算法设计的出发点,也是本篇文章接下来要讲的四位“经理候选人”。
- T_total(总服务时间)一个I/O请求从发出到完成的总耗时,这是衡量调度性能的核心指标。
- T_seek(寻道时间)磁头从当前位置移动到目标磁道所需的时间,与磁道距离成正比。
- T_rotate(旋转延迟)盘片旋转使目标扇区转到磁头下方的时间,平均约等于半圈。
- T_transfer(传输时间)数据从磁盘介质读出并经由接口传回内存的时间,通常远小于前两者。
CFQ公平队列
CFQ(Completely Fair Queueing)是Linux从2.6版本到4.x版本间默认的I/O调度器。它像一家坚持“绝对公平”的餐厅——不管客人点什么菜、点多少菜,前台经理都按桌轮流叫号:1号桌先上一道,2号桌上一道,3号桌上一道……转回来再给1号桌。这种“不患寡而患不均”的理念,让CFQ成为桌面环境最友善的调度器。
CFQ为每个进程维护一个独立的请求队列,并用时间片(slice)来调度。进程每获得一个时间片,最多可以提交一定数量的请求;如果某个进程当前没有请求,它的时间片自动让给其他进程。这样,即使某个进程疯狂发起I/O请求,也无法独占磁盘带宽——每个进程都能分到一口汤喝。
CFQ的公平性由“虚拟时间”(virtual time)精确记账。虚拟时间的增长速度与当前活跃进程数成正比:活跃进程越多,虚拟时间走得越快,使得每个进程在相同真实时间内获得大致相同的I/O份额。同时CFQ支持进程优先级(nice值),高优先级的进程可以获得更长的时间片,相当于餐厅里“VIP客人”可以获得更多叫号次数。
CFQ的好处显而易见——公平、不会饿死任何进程,桌面环境下多任务体验极佳。但代价也很真实:调度器频繁切换服务对象,导致磁头在磁道间来回奔波,增加了寻道开销。在高并发或吞吐密集的服务器场景下,CFQ的“过分公平”反而成了吞吐量的拖累,这也为Deadline算法登台创造了机会。
- V(t)(虚拟时间)CFQ用来衡量每个进程“享受了多少I/O服务”的账本记录。
- α(活跃进程数)当前确实有I/O请求排队等待服务的进程数量。
- β(总进程数)系统中所有参与I/O竞争的进程总数,两者比值决定公平时钟快慢。
- Δt(真实时间增量)距离上次更新虚拟时间所经过的真实时间长度。
期限调度算法
Deadline算法的理念与CFQ截然不同。如果CFQ是“轮流叫号的公平经理”,Deadline就像一家承诺出餐时间的连锁餐厅:每张点单都贴上“最晚出餐时间”标签,快超时的单子,后厨必须放下手里的活优先做。它不追求公平,只追求“不违约”。
Deadline内部维护四棵队列:两棵排序队列和两棵期限队列。排序队列按磁盘扇区号排序,作用是合并相邻请求、减少寻道距离,类似把同一灶台附近的菜品顺路一起做;期限队列按到期时间排序,作用是保证延迟。调度器平时从排序队列中取请求执行,但一旦某个请求逼近期限,就立刻“插队”优先处理。
Deadline最著名的策略是“读优先”——读请求的期限通常设为500毫秒,写请求的期限设为5秒。原因很直觉:读请求往往与应用执行直接相关(加载代码、查询数据库),而写请求有页缓存兜底,可以适当延后。读优先策略能显著减少应用的“卡顿感”,这也是数据库场景偏爱Deadline的根本原因。
Deadline像一位“有取舍”的经理:它不纠结于绝对的公平,而是抓住主要矛盾——先保证延迟敏感的应用不被饿死,再考虑整体吞吐。它允许写请求多等一会儿,但绝不会让写请求无限期饥饿。在数据库这类读多写少、延迟敏感的场景中,Deadline往往比CFQ表现得更加游刃有余。
- D(截止期限)调度器为每个请求计算的“最晚必须开始服务”的时间点。
- T_arrive(到达时间)请求进入调度器队列时打上的时间戳。
- T_expire(到期时间)请求允许在队列中等待的最长时间段,读短写长是Deadline的灵魂设定。
简单NOOP
NOOP(No Operation)是调度器中最“佛系”的一位经理。它就像一家只按点单先后顺序出餐的路边小店——客人什么顺序点单,后厨就什么顺序做,不插队、不调序、不搞任何花哨的优化。简单直接,甚至有些呆板,但在特定场合却恰如其分。
NOOP基于FIFO(先进先出)队列,本质上只做两件事:合并相邻扇区的请求和最基本的调度。它不关心进程优先级,不设期限,不做电梯调度优化。它的信条是:如果物理设备已经足够快、足够智能,就不需要调度器来“自作聪明”。
NOOP的主要适配场景有三个:第一是SSD,固态硬盘没有机械寻道,随机读写与顺序读写速度差距不大,调度优化毫无意义,反而徒增CPU开销;第二是NVMe固态硬盘,这类设备自带深度队列和内部调度能力,内核介入只会帮倒忙;第三是硬件RAID控制器,磁盘阵列卡自身已经具备成熟的调度逻辑,软件层再排序等于多此一举。
在餐厅比喻中,NOOP就是“厨房出菜极快、客人也不多”的小店经理——反正每道菜几秒钟就能上桌,何必费心设计复杂的排队策略?算法本身带来的CPU开销,在这种场景下反而成了多余的成本。NOOP的存在提醒我们一个道理:最好的优化,有时就是不做多余的优化。
- t_wait(n)(第n个请求的等待时间)请求从进入队列到被服务之间的排队时间。
- n(队列位置)请求在FIFO队列中的排位,完全由到达顺序决定。
- s_i(服务时间)第i个请求实际占用的磁盘读写时间。
带宽公平BFQ
BFQ(Budget Fair Queueing)可以看作CFQ的“进阶版”。如果说CFQ是轮流叫号,BFQ就是一位懂得“看人下菜碟”的精明经理:老客户(高权重进程)优先获得更多的出菜份额(带宽),新客户也不会被完全忽视——每个人都能吃得上饭,但重要客人的菜上得更快。
BFQ不再以时间片为单位调度,而是以“预算”(budget)为基本单位。每个进程拥有一个权重(weight),决定它能获得多少I/O带宽;BFQ按权重比例分配磁盘带宽,并为每个进程计算一个服务预算——一个时间片内最多可以发送的扇区数或请求数。实际运行时,调度器按预算给进程“定量供应”,既防止了浪费,也保证了公平配额。
BFQ在交互响应优化上下足了功夫:它能检测进程是否交互敏感,区分前台与后台进程,甚至在进程暂时没有I/O请求时,提前预测它的下一步需求。因此,在桌面系统、视频剪辑等场景中,BFQ能有效防止“一个大文件复制就让整个系统卡成幻灯片”的窘境——后台拷贝可以等,你拖动窗口的光标绝不能等。
不过,“聪明的经理”往往更费心思。BFQ的调度逻辑是所有算法中最复杂的,CPU开销也最高。在低端嵌入式设备或吞吐量极大的服务器上,这种“精打细算”反而可能拖慢整体速度。鱼与熊掌不可兼得——BFQ用更多的计算成本,换来了更细腻的带宽体验。
- B_i(进程i的带宽)进程i单位时间内能获得的I/O吞吐量,是衡量服务质量的关键指标。
- w_i(进程i的权重)由进程优先级和IO优先级共同决定的数字,权重越高重要性越大。
- Σw_j(权重总和)所有活跃进程的权重之和,作为归一化的分母。
- B_total(总带宽)磁盘在单位时间内能提供的最大数据吞吐量。
算法对比分析
现在,四位经理站在同一家“磁盘餐厅”前。我们用三组指标来评判:吞吐量(每秒能服务多少请求)、延迟(每个请求等多久)、公平性(每个进程是否都得到服务)。不同的“餐厅类型”,各有各的最优经理。
在HDD(机械硬盘)上,寻道是最主要的开销。CFQ和BFQ这类以公平为导向的调度器,由于频繁切换服务队列,导致磁头在磁道间“反复横跳”,吞吐量反而低于Deadline和NOOP——后两者会按扇区排序来减少磁头移动距离。这就像一个厨师如果频繁在相距很远的灶台之间来回跑,出菜效率一定不如按区域集中做菜的厨师。
在SSD(固态硬盘)上,没有机械寻道,所有基于磁道排序的优化收益都消失了。此时调度的比较变成了CPU开销的比拼:NOOP开销最小,CFQ/Deadline中等,BFQ最大。对于NVMe设备(随机访问延迟仅为微秒级),我们甚至可以直接绕过内核调度器,使用多队列(blk-mq)机制配合硬件自身调度,让设备自己管理自己。
总结一句话:HDD时代,调度器算法是性能的关键变量;SSD时代,调度器的意义逐渐被硬件进化所稀释。这就像马车时代,经验丰富的车夫能决定货物到达速度;而到了高铁时代,车夫的驾驶技巧已经不再重要——基础设施的进化重塑了整个行业的规则。
- D_avg(平均寻道距离)执行完n个请求后,磁头累计移动距离的平均值,是HDD吞吐的度量衡。
- pos_k(磁道位置)第k个请求目标数据所在的具体磁道号。
- |pos_k - pos_{k-1}|(相邻移动距离)磁头从上一个请求位置移动到当前请求位置的磁道跨度。
选择与配置
挑选调度器,本质是看你的“餐厅”开在什么街区、招待什么样的客人。如果你是数据库管理员,你的客人是大量并发查询——读多写少、延迟敏感,请选择Deadline,它能把读请求的响应时间压到最低,避免慢查询拖垮整个系统。
如果你是桌面用户,日常操作包含大量交互应用、偶尔还有几个后台大文件传输。BFQ和CFQ能帮你优雅地“护住”前台体验——滑动浏览器、播放视频时,不会被后台的cp或rsync卡成PPT。现代Linux发行版(Kernel 5.0+)通常默认使用BFQ或mq-deadline,正是为兼顾桌面与服务器场景而做的折中。
如果你的应用跑在SSD/NVMe上,NOOP(以none方式呈现)往往是最优解——它不抢CPU、不做无用优化,让设备自己发挥。配置命令也非常轻量:echo deadline > /sys/block/sda/queue/scheduler,即可在运行中切换调度器。若需要持久化,需修改内核启动参数或编写udev规则。
调度算法的选择没有银弹。好的工程师就像精明的餐厅老板,会先调研客源(工作负载)、核算成本(CPU开销)、再做试营业(性能测试),最后才决定聘请哪位经理(调度器),并在运营中持续调整。理解每种算法背后的权衡,远比死记硬背某个参数更有价值。
- T_budget(I/O总延迟)请求从发起到完成的总耗时,是用户可感知的最终指标。
- T_io(服务时间)磁盘实际读写数据所花的时间,由物理设备决定。
- T_queue(排队时间)请求在调度队列中等待的时间,由算法决策直接影响。
- T_sla(服务目标)业务侧允许的最大延迟阈值,如数据库查询超时上限。
AI 应用场景
AI训练数据加载管道
阶段:数据准备与预处理
解决的问题:深度学习训练需要高速读取海量图片、文本样本。传统方式中,数据加载线程与训练进程争抢磁盘I/O,导致GPU空转、训练吞吐波动剧烈。通过配置合适的I/O调度器(如Deadline,或SSD上的NOOP),数据读请求获得稳定的低延迟,训练管道吞吐量可提升20%-40%。
具体案例:某团队在8卡GPU服务器上训练图像分类模型,数据存储在NVMe SSD上。默认调度器导致数据加载吞吐在800MB/s到1.2GB/s之间剧烈波动。切换为none调度器并启用预读后,吞吐稳定在1.5GB/s,GPU利用率从70%提升至92%。
在线推理服务的数据库访问
阶段:模型推理与在线服务
解决的问题:推荐系统、智能客服等在线AI服务需要实时查询特征数据库。传统混部环境下,写日志进程的I/O会干扰读请求,导致推理延迟毛刺。Deadline算法的读优先策略恰好切中要害——读不被写干扰,P99延迟显著下降。
具体案例:某电商推荐系统使用MySQL存储用户特征,每秒约2万次读查询和500次写入。内核调度器从CFQ切换为Deadline后,读延迟P99从40ms降至12ms,在线推荐接口的超时率下降80%。
大规模模型训练的Checkpoint保存
阶段:模型训练
解决的问题:训练大模型时,周期性保存checkpoint会产生GB级写入风暴。在共享存储服务器上,这种写突发会挤压其他训练任务的读带宽。理解I/O调度并配置合理的调度策略(如BFQ为写进程限带宽、为训练进程保读带宽),可以显著降低checkpoint写入对其他任务的干扰。
具体案例:某大模型训练平台在存储节点上启用BFQ,为checkpoint写进程设置较低IO优先级,同时为训练数据读进程设置高权重。结果:checkpoint保存耗时仅增加10%,但同节点上其他训练任务的吞吐波动从30%降到了5%以内。
Python 演示
import randomfrom collections import deque class Request: """I/O请求模拟:进程号、扇区位置、读写类型、到达时间""" def __init__(self, pid, sector, rw, arrive): self.pid = pid self.sector = sector self.rw = rw self.arrive = arrive self.deadline = arrive + (0.5 if rw == 'R' else 5.0) def simulate_cfq(requests): """CFQ:按进程分组,轮转服务各队列头部请求""" queues = {pid: deque() for pid in set(r.pid for r in requests)} for r in requests: queues[r.pid].append(r) order = [] while queues: for pid in list(queues.keys()): if queues[pid]: order.append(queues[pid].popleft()) idle = False else: del queues[pid] return order def simulate_deadline(requests): """Deadline:读优先 + 期限最近者优先""" pool = requests[:] order = [] t = 0.0 while pool: ready = [r for r in pool if r.arrive <= t] if not ready: t = min(r.arrive for r in pool) continue urgent = [r for r in ready if t > r.deadline - 0.2] if urgent: sel = min(urgent, key=lambda r: r.deadline) else: reads = [r for r in ready if r.rw == 'R'] sel = min(reads, key=lambda r: r.deadline) if reads else min(ready, key=lambda r: r.deadline) order.append(sel) pool.remove(sel) t += 0.1 # 固定服务时间 return order def avg_wait(order): """计算平均排队等待时间""" t, total = 0.0, 0.0 for r in order: if t < r.arrive: t = r.arrive total += t - r.arrive t += 0.1 return total / len(order) random.seed(42)requests = [Request(random.randint(0, 2), random.randint(0, 1000), random.choice(['R', 'W']), i * 0.01) for i in range(30)] cfq_order = simulate_cfq(requests)dl_order = simulate_deadline(requests) print("CFQ 平均等待: %.3fs" % avg_wait(cfq_order))print("Deadline 平均等待: %.3fs" % avg_wait(dl_order))print("CFQ 前5个执行顺序:", [r.pid for r in cfq_order[:5]])print("Deadline 前5个执行顺序:", [r.pid for r in dl_order[:5]])
requests = [Request(random.randint(0, 2), ...)]随机生成30个I/O请求,包含3个进程、随机扇区和读写类型,模拟真实混合负载。queues[pid].popleft()CFQ从每个进程队列头部取请求,实现“轮流叫号”的公平调度。if not ready: t = min(r.arrive for r in pool)Deadline模拟中,若当前无请求到达则快进到下一请求到达时刻。urgent = [r for r in ready if t > r.deadline - 0.2]检查是否有快超时的请求,快超时就触发“插队”机制。sel = min(reads, key=lambda r: r.deadline) if reads else ...没有超时请求时,优先选择读请求中期限最近的,体现“读优先”策略。
常见误区
误区“Linux默认用CFQ,说明CFQ是综合最优的调度器,我直接用它就行。”
正解CFQ被选为默认调度器,是因为它在“通用场景”下表现均衡,兼顾了桌面交互和服务器吞吐,而不是因为它在任何场景都最优。就像一家餐厅的招牌菜,适合大多数食客,但不一定适合严格忌口的顾客。在数据库、SSD、NVMe等特定场景下,Deadline或NOOP可能远胜CFQ。选调度器要看工作负载类型,而不是迷信默认值。
为何常见:人倾向于认为“系统默认 = 官方推荐 = 最优解”,这是对“默认值=安全值”的朴素信任,忽略了默认值往往是为最大兼容性而非最佳性能设计的。
误区“Deadline总是优先读,写请求会被无限拖延,最后丢失数据。”
正解Deadline的读优先只是相对优先,并不代表写请求被放弃。每个写请求同样有一个5秒的期限兜底,一旦逼近期限就会进入“紧急通道”强制服务。这就像餐厅承诺“饮品优先制作”,但正餐绝不会无限期搁置——每道菜都有自己的保证时间。Deadline通过双向期限队列,同时保护读和写的性能边界,只是给读的优先级更高而已。
为何常见:人们看到“读优先”就直觉认为是“写饥饿”,忽略了Deadline算法中写请求也有期限保证这一个关键机制。
误区“SSD没有寻道,所以不需要调度器,随便设成NOOP就一了百了。”
正解即使SSD中寻道优化没有意义,调度器仍承担着请求合并、限流、公平性保护等职责。NOOP并不是“没有调度器”,而是一种“尽量少干预”的调度策略——它仍然会做相邻扇区合并。在NVMe和多队列(blk-mq)时代,硬件队列本身就实现了类似调度的机制,但公平性和限流仍需软件层配合。所以准确的说法是“SSD不需要寻道优化类调度”,而不是“完全不需要调度”。
为何常见:把“调度器=磁道排序器”混为一谈,忽略了调度器在合并、公平性、延迟控制上的多重角色。
误区“把调度器的目标延迟调得越低越好,这样所有请求都快。”
正解调度器存在“公平-延迟-吞吐”的三难权衡。刻意调低延迟目标,可能让调度器频繁切换队列,增加磁头无谓移动(HDD场景),反而降低整体吞吐;或者让紧急请求频繁插队,导致普通请求大面积超时。就像餐厅如果给每桌都承诺“3分钟上菜”,厨师只能每道菜做一口就换下一桌,最终所有桌都吃不饱。调参必须基于真实负载测试,而不是凭空拍脑袋。
为何常见:将系统的复杂权衡简化为单一指标优化,忽视了调度算法各性能维度之间的此消彼长关系。
面试题
Q1. CFQ调度器的核心设计理念是什么?
- A.最小化磁盘寻道距离
- B.保证进程间的I/O公平性← 正确答案
- C.优先处理读请求
- D.最大化CPU利用率
答案:B。CFQ(完全公平队列)的核心是“公平”,它通过时间片轮转和虚拟时间记账,让每个进程获得大致相同的I/O份额。选项A是Noop/电梯调度关注点,C是Deadline的特征,D与I/O调度无直接关系。
Q2. Deadline调度器中读请求的默认期限是多少?
- A.50毫秒
- B.500毫秒← 正确答案
- C.5秒
- D.1秒
答案:B。Deadline的关键设定是读请求期限500毫秒、写请求期限5秒。读请求期限短是为了降低应用可感知延迟,写请求放宽则利用页缓存兜底。A过短会导致频繁插队,C和D分别是写期限和中间值。
Q3. NOOP调度器最适合以下哪种设备?
- A.老式机械硬盘
- B.磁带存储设备
- C.企业级NVMe固态硬盘← 正确答案
- D.光盘驱动器
答案:C。NOOP采用FIFO策略,不做寻道优化,正适合没有机械寻道开销的NVMe SSD——设备自带的深度队列和内部调度能力已经足够强大。A和D是机械设备,需要寻道优化,NOOP会造成吞吐下降。
Q4. 在HDD环境下,相比CFQ,哪些算法通常能获得更高的吞吐量?
- A.Deadline← 正确答案
- B.NOOP← 正确答案
- C.BFQ
- D.CFQ
答案:AB。HDD的关键开销是寻道时间。CFQ的公平轮转导致磁头在磁道间频繁往返,吞吐下降;Deadline通过排序队列合并相邻扇区请求、NOOP保持FIFO顺序让自然局部性发挥作用,都能减少磁头移动。BFQ是CFQ的升级版,同样以公平为导向,并不会提升HDD吞吐。
Q5. BFQ与CFQ的共同目标是什么?
- A.保证进程间的I/O公平← 正确答案
- B.优先处理读请求
- C.完全按先来后到服务
- D.最小化CPU调度开销
答案:A。BFQ是CFQ的“进阶版”,两者本质都追求公平。区别在于CFQ以时间片为单位、按进程轮流服务,BFQ以预算和权重进行更精细的带宽分配。B是Deadline的目标,C是NOOP的特征,D则恰恰相反——BFQ的CPU开销恰恰较大。
Q6. 以下哪些场景适合选择Deadline调度器?
- A.读密集的数据库应用← 正确答案
- B.大文件顺序写入为主的服务
- C.Web服务器静态文件读取← 正确答案
- D.纯SSD下的高吞吐计算
答案:AC。Deadline的读优先和期限保证,最适合读多、延迟敏感的场景,数据库查询和Web静态文件读取都属于此类。B是写密集型,读优先策略反而可能损害写吞吐;D在SSD上调度意义减弱,更适合NOOP。
Q7. BFQ算法中“预算”(budget)的含义是什么?
- A.进程获得的时间片长度
- B.进程在一个周期内可提交的请求数或扇区数配额← 正确答案
- C.磁盘的剩余可用容量
- D.进程的CPU优先级
答案:B。BFQ将I/O带宽按权重分配,每个进程在一个“服务周期”内有一个预算上限——通常表示为最多可发送的扇区数或请求数。预算耗尽后该进程让出磁盘给其他进程。A是CFQ的概念,C和D与带宽预算无关。
Q8. 在Linux中,运行时切换SDA磁盘I/O调度器的命令是?
- A.
echo deadline > /sys/block/sda/queue/scheduler← 正确答案 - B.
sysctl -w vm.swappiness=10 - C.
mount -o noatime /dev/sda - D.
systemctl restart block-device
答案:A。切换调度器只需向sysfs中的scheduler文件写入目标算法名称,命令后还可加cat /sys/block/sda/queue/scheduler验证。B是调整内存交换倾向,C是挂载选项,D并不存在这个系统服务。
Q9. 关于SSD上I/O调度算法的说法,正确的有哪些?
- A.磁道排序优化不再有意义← 正确答案
- B.NOOP的CPU开销通常最低← 正确答案
- C.FIFO策略必然比Deadline慢
- D.NVMe常用blk-mq多队列对接硬件← 正确答案
答案:ABD。SSD无寻道,磁道排序优化失去收益,A正确;NOOP不做任何复杂排序,CPU开销最低,B正确;NVMe设备配合blk-mq多队列机制可充分发挥硬件并行能力,D正确;C的错误在于“必然”——FIFO在SSD上并不是“慢”,只是缺少延迟保护,吞吐并不必输。
Q10. CFQ中“虚拟时间”的主要用途是什么?
- A.记录磁盘的转速变化
- B.量化每个进程的I/O使用量,作为公平调度的账本← 正确答案
- C.控制读请求的到期时间
- D.合并相邻扇区的请求
答案:B。CFQ用虚拟时间为每个进程记账,虚拟时间增长速率与活跃进程数挂钩,进程按虚拟时间排队,从而实现“真实时间公平”。A是物理设备属性,C是Deadline的机制,D是NOOP和Deadline排序队列的特征。