Linux 写入为何比读取慢?

write() 更易卡住因内核写入路径长且可控性低:需经脏页管理、回写调度、设备队列等多层,而 read() 常命中页缓存或仅单次 I/O;脏页批量回写时进程阻塞,iostat 无负载但 vmstat 显示 pgpgout 飙高。

linux 写入为何比读取慢?

为什么 write()read() 更容易卡住

根本原因不在磁盘本身,而在内核的写入路径更长、可控性更低。读取通常能从页缓存直接返回(命中时),而写入必须经过脏页管理、回写调度、设备队列等多层缓冲与决策。

常见现象:write() 突然阻塞数秒,strace 显示卡在系统调用里;iostat 却没看到明显 I/O;vmstat 1pgpgout 飙高但 bi(块输入)几乎为 0——这说明脏页正在被内核批量回写,而非你的进程在直接写盘。

  • write() 默认是“异步提交到页缓存”,不等落盘;但当缓存快满(vm.dirty_ratio 触发)、或调用 fsync()/close() 时,内核会强制同步刷脏页,此时你的线程就会卡住
  • read() 若缓存命中,全程不碰磁盘;即使未命中,也只触发一次预读+单次 I/O,路径短、无累积效应
  • SSD 或 NVMe 上写放大、GC 延迟也会在回写阶段集中暴露,但用户感知为“写比读慢”

O_DIRECT 能绕过缓存加速写入吗

不能一概而论——它绕过了页缓存,但也放弃了内核的预读、合并、延迟调度等优化,实际效果取决于 workload 和硬件。

适用场景:已自行实现高效缓存/预取逻辑(如数据库)、写入流高度顺序且大小对齐(如 4K 对齐的大块日志)。

GNU make 中文手册 pdf版

GNU make 中文手册 pdf版

GNU makefile中文手册 pdf,文比较完整的讲述GNU make工具,涵盖GNU make的用法、语法。同时重点讨论如何为一个工程编写Makefile。阅读本书之前,读者应该对GNU的工具链和Linux的一些常用编程工具有一定的了解。诸如:gcc、as、ar、ld、yacc等本文比较完整的讲述GNU make工具,涵盖GNU make的用法、语法。重点讨论如何使用make来管理软件工程、以及如何为工程编写正确的Makefile。 本手册不是一个纯粹的语言翻译版本,其中对GNU make的一些语法

下载

  • 必须确保用户缓冲区地址和长度都按存储设备逻辑块大小对齐(通常是 512B 或 4K),否则 write() 直接返回 -EINVAL
  • 每次 write() 都真实下发 I/O 请求,无法合并;小块随机写 + O_DIRECT 会让 IOPS 爆表、延迟飙升
  • O_DIRECT 不保证元数据(如文件大小更新)落盘,fsync(O_SYNC) 仍需额外调用

哪些配置项真正影响写入延迟

关键不是调大缓存,而是控制脏页生成节奏和回写时机。默认值适合吞吐优先场景,对低延迟写入反而有害。

  • vm.dirty_ratio(默认 80):触发同步回写的脏页百分比上限;建议降至 30–50,避免突发刷盘阻塞
  • vm.dirty_background_ratio(默认 10):后台线程开始异步回写的阈值;建议设为 5–15,让刷盘更平滑
  • vm.dirty_expire_centisecs(默认 3000 = 30 秒):脏页最大驻留时间;若应用要求强一致性,可压到 500(5 秒)以内
  • /proc/sys/vm/swappiness 设为 0 可减少因内存压力导致的意外换出干扰写入路径

如何快速验证是否是内核回写导致的写延迟

不用上 perf 或 ftrace,几个简单命令就能定位:

  • 运行 watch -n 1 'cat /proc/meminfo | grep -E "Dirty|Writeback"':观察 Dirty 值是否周期性冲高后骤降(典型回写行为)
  • 执行 echo 1 > /proc/sys/vm/drop_caches 后再测写入——如果延迟大幅下降,说明原先是脏页积压所致(注意:这仅用于诊断,勿在生产环境乱用)
  • perf record -e 'syscalls:sys_enter_write' -a sleep 10 抓取写系统调用耗时分布,再 perf script 查看是否有大量 >100ms 的样本

真正难处理的是混合负载:一边有日志持续写入,一边有备份进程 dd if=/dev/sda of=/backup.img 扫盘——后者会污染页缓存并触发全局回写,导致前者写入抖动。这种干扰很难靠单个参数消除。

https://www.php.cn/faq/2023219.html

发表回复

Your email address will not be published. Required fields are marked *