内核参数调优:vm.dirty_ratio、nr_requests 等关键参数
聊到 I/O 性能调优很多人第一反应是换 SSD、加内存条。但说实话硬件砸钱谁都会真正见功夫的地方是操作系统内核那几十个参数怎么调。我见过太多项目硬件配置拉满结果跑个数据库还是卡成幻灯片——查到最后就是几个内核参数没动过。今天咱们就聊聊 I/O 栈里最关键的几个旋钮vm.dirty_ratio、vm.dirty_background_ratio、nr_requests还有它们的小伙伴们。这些东西调好了你的磁盘吞吐能翻倍调错了数据丢了都不知道怎么丢的。1. 脏页回写vm.dirty_ratio 与 vm.dirty_background_ratio先说说脏页。你写文件时数据不会直接落盘而是先写到内存里的 Page Cache。这些被修改过、还没写回磁盘的内存页就叫「脏页」。内核有一整套机制在后台默默地把脏页刷回磁盘。这两个参数就是控制这个刷盘行为的阀门参数默认值含义vm.dirty_background_ratio10当脏页占内存比例达到此值时内核后台线程开始异步刷盘vm.dirty_ratio20当脏页占内存比例达到此值时写操作会被同步阻塞强制刷盘说白了dirty_background_ratio是「温柔提醒」内核说脏页有点多了我派后台线程慢慢刷。而dirty_ratio是「拍桌子」——脏页太多了所有写进程都给我停下来等刷完再说。核心原则这两个值设得越大写操作的突发吞吐越高但一旦触发同步阻塞延迟会剧烈抖动。设得太小磁盘频繁刷写吞吐上不去。我在项目中遇到过一台日志服务器白天高峰期写延迟动不动飙到 500ms 以上。查了一圈发现dirty_ratio还是默认的 20%但机器内存有 256GB。你想想看20% 就是 51GB 的脏页一旦触发同步阻塞那得刷多久后来我把dirty_ratio降到 5%dirty_background_ratio降到 2%延迟瞬间稳定在 10ms 以内。我的调优建议对于数据库、Redis 等对延迟敏感的应用dirty_background_ratio设 2-5%dirty_ratio设 5-10%对于大文件写入、批量导入等吞吐优先的场景可以适当调高比如 10% 和 20%如果磁盘是 SSD建议把值设低一些——SSD 随机写性能好频繁刷盘影响不大但能换来更平滑的延迟2. 块设备队列nr_requests接下来是nr_requests。这个参数控制的是块设备请求队列的深度。你可以把它想象成磁盘门口的一个缓冲区——应用层发来的 I/O 请求先在这里排队然后由 I/O 调度器决定谁先谁后。查看当前值# 查看某个块设备的 nr_requests cat /sys/block/sda/queue/nr_requests # 通常默认是 128 或 256这个值设大了队列能容纳更多请求磁盘可以更好地合并相邻请求提升吞吐。但代价是单个请求的排队延迟会增加。设小了队列容易满新请求会被直接拒绝应用层就得重试或阻塞。我记得有一次帮一个视频平台调优他们的转码服务器写入 HDD 阵列时吞吐死活上不去。我一看nr_requests只有 64而磁盘是 7200 转的机械盘寻道时间本来就长。把nr_requests调到 512 后吞吐直接翻了一倍。为什么因为队列深了I/O 调度器有更多机会做合并和排序减少了磁头来回移动的次数。注意对于 NVMe SSDnr_requests不宜设得过大。NVMe 的延迟已经很低了队列太深反而会增加 CPU 开销和内存占用。我个人习惯给 NVMe 设 128-256给 HDD 设 512-1024。3. I/O 调度器选择与参数说到队列就不得不提 I/O 调度器。Linux 内核提供了几种调度算法调度器适用场景特点mq-deadline通用场景HDD 和 SSD 都可用保证每个请求的 deadline避免饿死bfq桌面、交互式应用按进程分配 I/O 带宽公平性好kyber低延迟场景NVMe SSD根据延迟动态调整队列深度延迟可控none高性能 NVMe SSD不做调度直接下发CPU 开销最低查看和修改当前调度器# 查看 cat /sys/block/sda/queue/scheduler # 修改临时 echo mq-deadline /sys/block/sda/queue/scheduler # 永久修改grub 或 udev 规则 # 在 /etc/default/grub 中添加 elevatormq-deadline我曾经踩过一个坑一台全闪存存储节点用了默认的 mq-deadline结果 4K 随机读延迟一直在 200μs 左右下不去。换成 none 调度器后延迟直接降到 80μs。说白了NVMe SSD 本身已经足够智能不需要内核再帮它做调度反而多了一层开销。4. 其他关键参数速览除了上面几个还有几个参数我经常调vm.dirty_expire_centisecs默认 3000即 30 秒脏页最多能存活多久。超过这个时间内核会强制刷盘。对于数据安全要求高的场景可以调小到 500-1000。vm.dirty_writeback_centisecs默认 500即 5 秒内核后台刷盘线程的唤醒间隔。调小可以更及时地刷脏页但会增加 CPU 开销。block/queue/read_ahead_kb预读大小。顺序读场景可以调大比如 4096 KB随机读场景建议调小甚至关闭。block/queue/max_sectors_kb单次 I/O 的最大大小。对于大块传输场景可以调大到 1024 或 2048 KB。快速查看所有 I/O 相关参数# 查看块设备队列参数 ls /sys/block/sda/queue/ # 查看内存脏页参数 sysctl -a | grep dirty5. 知识体系内核 I/O 参数调优全景下面这张图是我自己总结的内核 I/O 参数调优的核心逻辑。你可以看到从应用层写数据到最终落盘中间经过了三个关键关卡Page Cache、块设备队列、磁盘控制器。每个关卡都有对应的参数可以调。6. 实战一套完整的调优流程说了这么多理论咱们来点实际的。假设你有一台 64GB 内存、NVMe SSD 的数据库服务器该怎么调# 1. 针对低延迟场景调小脏页阈值 sysctl -w vm.dirty_background_ratio2 sysctl -w vm.dirty_ratio5 sysctl -w vm.dirty_expire_centisecs500 sysctl -w vm.dirty_writeback_centisecs100 # 2. NVMe SSD 用 none 调度器减少开销 echo none /sys/block/nvme0n1/queue/scheduler # 3. 队列深度适中避免 CPU 浪费 echo 128 /sys/block/nvme0n1/queue/nr_requests # 4. 关闭预读数据库随机读为主 echo 0 /sys/block/nvme0n1/queue/read_ahead_kb # 5. 单次 I/O 大小设为 1MB适合数据库日志写入 echo 1024 /sys/block/nvme0n1/queue/max_sectors_kb重要提醒以上修改都是临时的重启后失效。要永久生效请写入/etc/sysctl.conf或使用sysctl.d配置文件。块设备参数可以通过 udev 规则或 systemd 服务来设置。我曾经帮一个电商平台做双十一前的压测他们的 MySQL 服务器在高峰时写延迟从 2ms 飙到 200ms。我按上面的思路调了一遍延迟稳定在 1ms 以内。说白了内核参数调优不是什么玄学就是搞清楚数据流经的每个环节然后对症下药。嗯关于内核参数调优今天就聊到这儿。记住一个原则没有银弹每个参数都要结合你的硬件、负载和业务场景来权衡。多压测、多观察、多调整慢慢你就能找到那个「甜点」。

相关新闻

CocosBuilder 3.0 场景编辑器实战:从 .ccb 文件到多平台发布避坑指南

CocosBuilder 3.0 场景编辑器实战:从 .ccb 文件到多平台发布避坑指南

简介:CocosBuilder3.0 是一款面向 Cocos2d-x 的可视化游戏场景编辑器,专为 2D 游戏和应用交互内容设计,帮助设计师与程序员通过节点拖放、属性调整、事件绑定和实时预览完成界面与关卡搭建,大幅降低纯编码门槛。该版本针对现代 Co…

2026/10/13 7:12:57 阅读更多 →
Python多线程入门教程

Python多线程入门教程

前言 学 Python 多线程,第一步要先把预期摆正:多线程不是让程序算得更快的万能药。它擅长的是「一边等、一边干活」——比如同时下载几十个页面、同时读写多个文件。如果你的瓶颈是一大堆计算,多线程帮不上忙,原因在 GIL&#xff…

2026/10/13 7:12:57 阅读更多 →
TensorFlow工程化实战:从自定义训练循环到跨平台部署的完整链路

TensorFlow工程化实战:从自定义训练循环到跨平台部署的完整链路

1. 为什么“tensorflow”这个标题值得单独拎出来聊如果你在搜索引擎里敲下“tensorflow”这个词,跳出来的结果大概率是官方文档、API手册、安装教程三件套。但真正在一线写过模型、调过参、部署过服务的人都知道,这个标题背后藏着的不是一个库那么简单&a…

2026/10/13 7:12:57 阅读更多 →

最新新闻

SQL UNIQUE约束详解:原理、数据库差异与防重复设计实践

SQL UNIQUE约束详解:原理、数据库差异与防重复设计实践

1. UNIQUE约束到底是什么,为什么你需要它做数据库设计这些年,我见过太多因为“忘记加唯一约束”而崩溃的业务系统。最典型的场景:用户注册接口被脚本刷了一遍,username重复了;订单表里同一笔订单被回调程序insert了两次…

2026/10/13 7:55:19 阅读更多 →
Agent-Skills:智能体原子化能力的设计与工程实践

Agent-Skills:智能体原子化能力的设计与工程实践

1. “agent-skills”不是新词,而是智能体能力体系的命名共识 最近在多个技术社区、开源项目文档和内部架构评审会上,“agent-skills”这个组合词出现频率陡增——它既不指代某个具体开源库,也不是某家公司的私有协议,而是一类设计…

2026/10/13 7:55:19 阅读更多 →
Flink DataStream与Table API转换实战:Schema推导、时间属性与常见避坑指南

Flink DataStream与Table API转换实战:Schema推导、时间属性与常见避坑指南

做实时数据处理这几年,Flink的DataStream和Table API来回切换是我用得最频繁的操作之一。刚接触那会儿,总觉得这两套API是两套独立的体系,流上处理业务逻辑用DataStream,做统计查询用Table,中间隔着一道说不清的墙。后…

2026/10/13 7:55:19 阅读更多 →
LiteLLM:大模型API统一网关与智能路由实战指南

LiteLLM:大模型API统一网关与智能路由实战指南

1. LiteLLM不是另一个大模型,而是一把“万能适配器”最近在几个技术群和开源社区里,频繁看到有人发问:“LiteLLM到底是个啥?是又一个新模型吗?”“它和Ollama、LM Studio有什么区别?”——这种误解非常典型…

2026/10/13 7:55:19 阅读更多 →
LiteLLM:大模型API统一接入与智能路由实战指南

LiteLLM:大模型API统一接入与智能路由实战指南

1. 为什么“litellm”突然在开发者圈里被高频提及——它不是新模型,而是新范式最近两周,在多个技术社区、内部分享会和开源项目讨论区里,“litellm”这个词出现的频率明显升高。它不像Llama、Qwen或Claude那样代表一个具体的大语言模型&#…

2026/10/13 7:55:19 阅读更多 →
开源代码审查实战:流程设计、工具配置与团队落地方法

开源代码审查实战:流程设计、工具配置与团队落地方法

代码审查这事儿,我过去几年一直想好好聊一聊。初看上去,open-code-review 这个项目标题没什么特别,好像就是把自己团队做代码评审的过程、工具和规范整理出来,开源给社区用。但如果真这么理解,那就有点浪费了。代码审查…

2026/10/13 7:54:17 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →