cgroup v2 io.weight 调整块设备相对优先级
我第一次用 cgroup v2 调整磁盘任务优先级时,最容易误解的是把 io.weight 当成“给这个服务固定多少 MB/s”。它实际表达的是同级 cgroup 在有竞争时对 I/O 资源的相对份额:默认值是 100,可写范围是 1 到 10000。因此,两个都在忙的同级组可以用 100 和 500 表达大约五比一的权重关系,但这不是硬带宽保证。
官方地址:https://docs.kernel.org/admin-guide/cgroup-v2.html
把 io.weight 当成“争用时的相对优先级”,把 io.max 当成“绝对 BPS/IOPS 限制”,再确认当前块设备和 I/O 控制器支持权重,配置才不会看起来写成功、实际却没有可观察差异。
io.weight 到底调整了什么
cgroup v2 的 io 控制器管理 I/O 资源分配。io.weight 只存在于非根 cgroup,默认行通常是 default 100;除此之外,还可以按设备的 major:minor 写覆盖项。权重越高,表示该 cgroup 在和兄弟组同时竞争同一个 I/O 资源时可以获得更高的相对份额。
这里有两个很重要的前提。第一,权重是同级比较,不是跨整棵层级树直接比较;第二,只有真正活跃、正在争用资源的组才会参与分配。空闲组不会因为配置了很高的数字就预先占走带宽,所以单独压测一个组时,常常看不出 100 和 500 的差别。

内核文档还明确区分了控制器实现:绝对 BPS/IOPS 限制由 blk-throttle 提供;权重型比例控制由 iocost 成本模型,以及使用 BFQ 调度器时的 BFQ cgroup 支持提供。因此,写入文件成功不等于当前设备一定会按预期表现出比例差异。
先准备两个真正同级的 cgroup
我会先把实验缩小成两个同级目录,让它们运行相同类型的 I/O 工作负载。下面假定系统已经挂载 cgroup v2,并且当前 shell 具备创建层级、启用控制器和迁移进程所需的权限。示例只展示配置边界,不会替你选择生产服务。
# 查看当前是否是 cgroup v2,以及 io 控制器是否可用 stat -fc %T /sys/fs/cgroup cat /sys/fs/cgroup/cgroup.controllers # 建立两个同级工作组,父级需要先把 io 控制器下放给子树 mkdir -p /sys/fs/cgroup/io-background /sys/fs/cgroup/io-interactive echo +io > /sys/fs/cgroup/cgroup.subtree_control # 让两个工作组拥有明确的默认权重,便于后续观察相对关系 echo "default 100" > /sys/fs/cgroup/io-background/io.weight echo "default 500" > /sys/fs/cgroup/io-interactive/io.weight # 把目标进程的 PID 写入 cgroup.procs;生产环境应使用服务管理器统一迁移 echo "$PID_BACKGROUND" > /sys/fs/cgroup/io-background/cgroup.procs echo "$PID_INTERACTIVE" > /sys/fs/cgroup/io-interactive/cgroup.procs
cgroup.subtree_control 的写入必须发生在父级,且子组中不能有不满足层级规则的进程;如果收到权限、忙或层级相关错误,先处理层级状态,不要把它误判为权重值不生效。实际服务通常由 systemd、容器运行时或编排器管理 cgroup,直接写系统树更适合隔离实验。
给某个块设备单独设置权重
默认权重适合“这个 cgroup 对所有相关设备都采用同一优先级”的场景。如果一个组在系统盘和数据盘上的策略不同,可以追加 major:minor 设备覆盖。先用 lsblk 找到设备号,再把覆盖写入对应 cgroup 的 io.weight。
# 读取块设备名称和 major:minor,避免凭设备名猜测覆盖目标 lsblk -o NAME,MAJ:MIN,MOUNTPOINTS # 假定目标设备为 8:16,只提高交互组在该设备上的相对权重 echo "8:16 500" > /sys/fs/cgroup/io-interactive/io.weight # 同一个文件会同时显示默认值和设备覆盖,读取结果确认写入格式 cat /sys/fs/cgroup/io-interactive/io.weight
设备覆盖的格式是 major:minor weight,默认值则可以写成单独的数字或 default weight。不要把 8:16 当作永远代表某块固定磁盘:设备重建、虚拟机映射和容器环境都可能改变 major:minor,生产配置应由启动时发现结果或明确的设备管理流程生成。

为什么单看配置文件还不够
我在调这个参数时,第一次复查只看到了 io.weight 里的数字,后来才发现测试盘上根本没有两个组同时产生足够的 I/O。复查至少要把“配置被接受”和“争用时出现预期行为”分成两件事。
# 查看两个组的权重配置,确认默认项或设备覆盖确实存在 cat /sys/fs/cgroup/io-background/io.weight cat /sys/fs/cgroup/io-interactive/io.weight # 读取按 major:minor 统计的读写字节、IO 次数和丢弃数据 cat /sys/fs/cgroup/io-background/io.stat cat /sys/fs/cgroup/io-interactive/io.stat # 在两个组都持续读写同一设备时重复采样,才有机会观察比例差异 sleep 5 cat /sys/fs/cgroup/io-background/io.stat cat /sys/fs/cgroup/io-interactive/io.stat
io.stat 提供按设备记录的读写字节数、读写 I/O 次数以及 discard 统计。它能告诉你两个组实际对哪些设备产生了多少 I/O,但不能单独证明某个测试已经达到稳定比例。要做有意义的比较,应固定文件集、并发度和测试时长,让两个组同时工作,并记录设备调度器、缓存影响和测试阶段。
如果写入 io.weight 没有报错,却始终观察不到差别,优先排查四件事:是否真的为 cgroup v2;两个工作负载是否位于同一父级;目标设备是否支持当前内核路径的权重控制;测试是否存在足够竞争。不要只把数字从 500 改到 5000,然后把无差异归因于“内核忽略了配置”。
权重、硬限制和清理动作怎么取舍
io.weight 适合“都要跑,但某类工作更重要”的场景,例如交互任务和后台归档共同使用一块盘。若需求是“这个服务最多只能读 20 MB/s 或每秒 5000 次 I/O”,应看 io.max,而不是把权重调得很低。权重不会把上限固定在某个吞吐量上,也不会在没有竞争时主动制造限速。
# 清除某个设备的专用覆盖,让它回到该 cgroup 的 default 权重 echo "8:16 default" > /sys/fs/cgroup/io-interactive/io.weight # 重新读取文件,确认该设备覆盖不再出现在结果中 cat /sys/fs/cgroup/io-interactive/io.weight # 实验结束后先停止或迁回工作进程,再移除空的 cgroup 目录 # 下面的路径只是示意,生产环境应由服务管理器执行回收 rmdir /sys/fs/cgroup/io-background rmdir /sys/fs/cgroup/io-interactive
对我来说,最稳妥的配置顺序是:先用默认权重验证两个同级组能产生可重复的争用,再给单一设备加覆盖,最后才考虑和 io.max 组合。这样每次改动只改变一个变量,也更容易从 io.stat 和调度器状态中解释结果。
常见问题
io.weight 设成 1000,是不是固定获得 1000 份带宽?
不是。它是相对权重,只有与同级、同时活跃的 cgroup 发生竞争时才有比较意义;实际份额还受设备、调度器、缓存和工作负载影响。
为什么只给一个 cgroup 设置高权重看不出变化?
没有竞争时,资源本来就可能被它独占。请让至少两个同级组同时访问同一设备,并用 io.stat 采样,而不是只读取配置文件。
io.weight 和 io.max 应该选哪个?
需要相对优先级时选 io.weight;需要绝对 BPS 或 IOPS 上限时看 io.max。两者可以在明确目标后组合使用。
设备覆盖删除后为什么又出现了?
常见原因是启动脚本、systemd 或容器运行时再次写入配置,也可能是设备 major:minor 发生变化。应检查实际的 cgroup 管理者和启动流程。
cgroup v2 的 io.weight 最适合做“相对优先级”这件事:先保证两个工作组在正确层级中,再确认目标设备支持权重控制,最后在真实争用期间结合 io.stat 判断。只记住一个数字而忽略层级和设备条件,通常比不调参数更难排查。
go fix inline 分析器识别内联建议的条件
- 上一篇
- go fix inline 分析器识别内联建议的条件
- 下一篇
- CSS scroll-driven animations 绑定滚动进度
-
- 文章 · linux | 26分钟前 | 容器 · Linux · Linux mount namespace 挂载传播 bind mount shared mount
- mount namespace 中绑定挂载的传播属性
- 342浏览 收藏
-
- 文章 · linux | 2小时前 |
- ip rule 与多路由表实现策略路由
- 406浏览 收藏
-
- 文章 · linux | 3小时前 |
- nftables 动态集合维护临时封禁地址
- 248浏览 收藏
-
- 文章 · linux | 5小时前 | Linux · journalctl Linux日志 journald systemd-journald Storage=persistent
- journald Storage=persistent 保留重启前日志
- 147浏览 收藏
-
- 文章 · linux | 8小时前 |
- systemd watchdog 监测服务心跳的配置方法
- 482浏览 收藏
-
- 文章 · linux | 20小时前 |
- Linux zram 写回如何在内存与磁盘间平衡
- 373浏览 收藏
-
- 文章 · linux | 22小时前 |
- Linux Landlock 怎样限制普通进程访问文件目录
- 151浏览 收藏
-
- 文章 · linux | 1天前 |
- Linux dm-verity 如何校验只读根文件系统
- 190浏览 收藏
-
- 文章 · linux | 1天前 |
- Linux nftables 集合如何动态维护封禁地址
- 193浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 408次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 484次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 493次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 438次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 266次使用
-
- Go语言中的IO操作及Flag包的用法
- 2022-12-30 491浏览
-
- 详解golang执行Linuxshell命令完整场景下的使用方法
- 2023-01-07 426浏览
-
- go程序部署到linux上运行的实现方法
- 2023-01-02 387浏览
-
- Linux系统下Go语言开发环境搭建
- 2023-01-07 242浏览
-
- Go语言io pipe源码分析详情
- 2023-01-07 237浏览

