服务器入坑指北:虚拟盘上的 I/O 调度取舍

举报
Tulpartner 发表于 2026/11/01 09:10:10 2026/11/01
【摘要】 说"换成某个调度器能更快",照着改了,结果没什么感觉;不知道该不该改,也不确定改了到底有没有用;同一台机器上好几块盘共用,改了个全局设置,别的地方反而变慢。这一层能起到的作用常常被稀释——客户机看到的是虚拟设备,真正的排队多半发生在宿主侧;两层都排队,等于多了一层管理。所以判据不是"哪个名字更高级",而是"改动之后,你的负载指标有没有真的变好"。

听说"换成某个调度器能更快",照着改了,结果没什么感觉;不知道该不该改,也不确定改了到底有没有用;同一台机器上好几块盘共用,改了个全局设置,别的地方反而变慢。
这类困惑的根源是:这一层能起到的作用常常被稀释——客户机看到的是虚拟设备,真正的排队多半发生在宿主侧;两层都排队,等于多了一层管理。所以判据不是"哪个名字更高级",而是"改动之后,你的负载指标有没有真的变好"。
这篇先讲怎么读现状(唯一可信的现读方式),再给官方的选择逻辑、虚拟盘上为什么常常白改,以及"只对匹配设备改、收益不足就回滚"的动作与判据。设备名与性能数字一律用占位符。另外把话说在前面:不要在生产盘上跑写压测。

先读现状:设备类型与当前生效项

当前生效项怎么读:读某块设备的调度器文件,列表里被方括号括住的那一个,就是当前生效的——这是唯一可信的现读方式。列表的形态是几个名字并列、其中一个在方括号里。
设备类型:机械盘、固态盘、虚拟设备——内核选默认值时的依据就是设备类型,所以"先认清这是什么盘",比"先记住哪个名字更快"重要。
顺序反了的代价:拿着网上的参数表乱套——不看设备类型、也不看当前生效项,上来就改。

# 只读读取(设备名一律用占位符)
cat /sys/block/<设备>/queue/scheduler      # 调度器列表:方括号里的那个才是当前生效项
cat /sys/block/<设备>/queue/nr_requests    # 队列相关参数的形态(数值按你的机器定,别照抄)
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT         # 设备类型:虚拟还是物理,先有个判断
# 驱动信息:需要时进一步确认这块盘的类型与能力

官方的选择逻辑:按设备与负载选

设备 / 负载 官方推荐方向 理由一句话 不适合的情况
传统机械盘 限期类或面向交互的加权方案 机械盘有真实寻道,排序有价值 已经换成固态时,这类排序的收益不明显
高性能固态,或"计算受限而存储很快"的系统 “不用调度器”(备选是轻量方案) 设备本身够快、并行度高,上层再排一次队反而多一层管理 设备其实是共享或虚拟设备、真实排队在别处时
桌面 / 交互场景 面向交互的加权方案 优先保证交互响应 服务端批处理负载用不到它
虚拟客户机 限期类 在客户机里保持一个轻量、可预测的排队顺序 主机总线驱动支持多队列时,可以改用"不用调度器"

官方还给两条明确的建议:内核自动选出的通常已经是合适的选择;确实需要别的,应当按设备匹配规则、只对匹配到的设备切换,而不是全机统一改。
表格里"虚拟客户机"那一行的两个方向并不矛盾:当主机侧的总线驱动支持多队列时,设备本身能并行接收请求,上层再做串行排序的价值就小了,所以可以用"不用调度器";否则保守一点,用限期类更稳。判据是:先现读主机侧总线驱动是否支持多队列,再决定用哪一档。现读入口按本机为准:可以看该设备对应的驱动信息与队列数量一类信息。

为什么在虚拟盘上常常"改了没感觉"

两条机制:

  1. 客户机看到的是虚拟块设备,真实的调度往往发生在宿主侧。两层都排队,等于叠了一层管理,收益自然被稀释;
  2. 请求到达宿主之后,由后端存储统一排队——客户机这一层的排序能力,能起到的作用是有限的。
    所以判据只有一条:改动之后,你的负载指标有没有真的变好。名字更好听、参数更"高级",都不构成理由。
    反过来说:如果你在同一负载下改完却没有可测量的变化,那多半说明瓶颈不在这一层——这时正确的动作是去看存储能力、后端与错峰,而不是继续换调度器名字。
    还要记住一个前提:这台机器的存储能力(IOPS 与带宽)由机型与云盘类型决定。如果瓶颈在存储能力或共享后端,调度器这一层再怎么调也解决不了——这时候该做的动作是换盘型、换机型、错峰,而不是继续换调度器名字。

取舍:只改匹配设备,收益不足就回滚

别全机改:全机统一会把不匹配的设备一起换掉——例如机械盘被塞进面向固态的选项。结果往往是一个地方没变好,另一个地方变差了。
优先改匹配设备:按设备匹配规则下发,并持久化(否则重启就变回去)。判据是:只有匹配的设备变了,其它设备原样。还要注意因果顺序:规则写完要让系统重新读取(通常需要重载或重启才会被读到),然后才谈"重启后仍是你的选择"。
记录原值:动手前把当前生效项记下来,这是回滚的依据。
收益不足就回滚:"改了没坏"不是保留它的理由。不回滚、也不记录,等于给系统留下一次没人验证过的变更。

# 动作形态(只给顺序;不在生产环境直接试)
# 1) 记录原值:当前生效项(就是列表里方括号中的那个)
# 2) 运行时切换:写该设备的队列文件(立即生效,重启丢失)
# 3) 持久化:按设备匹配规则下发,只对匹配到的设备生效(重启后仍是你的选择)
# 4) 复核:现读生效项——只有匹配设备变了,其它设备原样
# 回滚:把值改回原值(或删掉那条匹配规则),再复核现读回到原值

收益怎么判:用你自己的负载,同口径前后比

指标 改前基线怎么取 改后怎么比 结论
业务响应时间(你的关键请求) 在同一个业务时段取一段稳定期的值 同一时段、同一口径再取一段 明显变好 → 有效;没有变化 → 无收益,应回滚
设备的排队与等待形态 现读队列相关参数与等待情况 用同样的方式现读 排队变长、等待变差 → 应回滚
业务吞吐 同一时段、同一接口 同上 只有吞吐上升、响应没有变差,才算改善
三条纪律:
  1. 用真实业务请求来判断,不要拿别人的基准数字当自己的结论;
  2. 不要在生产盘上跑写压测——那会把"验证"本身变成事故;确实需要压测,就在副本或测试盘上做;
  3. 同一指标、同一口径前后比(这条与"两个指标打架时先信谁"的纪律一致)。
    取基线时有两个细节:同一个业务时段(避开与业务无关的窗口,例如备份时段),以及同一类请求(读密集与写密集的请求分开看——它们的瓶颈可能并不相同)。如果业务本身波动很大,宁可把观察窗口拉长,也不要拿两段性质不同的数据互比。

验证清单:每项一条判据

  • 现读生效项=你期望的那个,并且只有匹配设备变了、其它设备原样。
  • 重启后仍是你的选择:持久化生效。
  • 同一指标、同一时段前后对比有明显改善。
  • 其它设备没有变差:全机层面的指标也要复核一遍。
  • 回滚可用:把值改回去,现读能回到原值。
  • 验证方式固定成一句话:现读确认范围与持久化、同口径对比确认收益,两者都对,才算通过。

这篇不解决什么

  • 不处理文件系统与回收:讲《文件系统选型与回收取舍》的那篇在文件系统与回收层;本篇在块设备调度层。
  • 不处理异常分支:讲《云盘变慢或报 I/O 错误时你能做什么》的那篇处理变慢与报错的取证与迁移;本篇处理常态调优的取舍——要不要动调度器、怎么判收益。
  • 不重复读数口径理论:讲《内存口径打架时信谁》的那篇是读数口径纪律;本篇只沿用它的"同口径前后比"这一条要求。

踩坑清单

  • 照抄网上的参数表:不看设备类型,也不看当前生效项。
  • 全机统一改:不匹配的设备被误伤,一个地方没变好、另一个变差。
  • 只改运行时、不持久化:重启之后变回默认,还以为自己改过。
  • 改了不回滚也不记录:留下一次没人验证过的变更。
  • 用别人的基准数字当自己的结论:硬件与负载都不同。
  • 在生产盘上跑写压测:把验证做成了事故。
  • 拿"感觉快了"当判据:没有同口径的前后对比。
  • 忘了宿主侧也在排队:以为客户机这一层是决定性的。
  • 瓶颈其实在存储能力或共享后端,却在调度器上反复折腾。
  • 改完不看同一指标的前后对比:无法判断有没有收益。
  • 把"内核默认选的那个"当成需要改的对象:默认值通常已经是合适的选择。
  • 只读一次列表就下结论:要看清方括号在哪里,而不是只看有哪些名字。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。