登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

Linux /proc/PID/io 怎么看进程真实磁盘读写:rchar、read_bytes 与 write_bytes 的区别

来源:17golang原创

时间:2026-08-24 08:31:29 224浏览 收藏

排查 Linux 服务“读写量暴涨”时,最容易被一组数字带偏:rcharwchar 很大,只能说明进程通过系统调用搬运过多少字节,并不能直接等同于磁盘设备真的完成了多少读写。判断磁盘压力,要把它们和 read_byteswrite_bytes 放在一起看。

要点速览
  • rchar/wchar 是进程读写请求经过内核接口的累计量,页缓存也会让它们增长。
  • read_bytes/write_bytes 更接近块设备层实际完成的读写量,但不能代替设备级监控。
  • 连续采样同一个 PID,配合文件描述符、文件系统和磁盘指标,才能判断是缓存命中、回写积压还是直接 I/O。
  • cancelled_write_bytes 变大时,要重点检查截断、覆盖和临时文件清理造成的写入抵消。
Linux proc PID io 中 rchar wchar 与 read_bytes write_bytes 的读写计数关系

先确认四个字段到底在统计什么

执行 cat /proc/$PID/io,常见输出类似下面这样:

rchar: 184320000
wchar: 62914560
syscr: 42000
syscw: 18000
read_bytes: 4096000
write_bytes: 52428800
cancelled_write_bytes: 0

rcharwchar 统计的是进程通过读写相关系统调用传递的字节数;它们会受到页缓存影响。比如文件已经在内存中,进程仍然完成了一次读取请求,rchar 会增加,但底层块设备可能没有新增读取。

read_byteswrite_bytes 统计的是更靠近存储层的读写量。它们适合回答“这个进程让内核实际从块设备读了多少、向块设备写了多少”,但仍是进程维度的累计计数,不能取代 iostat 或云盘监控对设备队列、延迟和吞吐的观察。

字段适合回答不能直接说明
rchar / wchar进程向读写接口传递了多少字节磁盘是否真的完成了同等读写
read_bytes / write_bytes进程引起的块设备读写累计量单次请求延迟、设备队列长度
cancelled_write_bytes有多少写入后来被取消或抵消数据是否已经安全落盘

用连续采样把累计值变成速率

单次查看只能看到进程从启动以来的总量。更实用的做法是保存两次读数,再除以采样间隔:

PID=2481
awk '/^(rchar|wchar|read_bytes|write_bytes|cancelled_write_bytes):/ {print}' /proc/$PID/io
sleep 5
awk '/^(rchar|wchar|read_bytes|write_bytes|cancelled_write_bytes):/ {print}' /proc/$PID/io

例如 5 秒内 wchar 增加 500 MB,而 write_bytes 只增加 40 MB,通常说明大量写入先进入页缓存,不能据此断言磁盘已经写入 500 MB。反过来,write_bytes 增长接近 wchar,并且设备延迟同步升高,才更像真实存储压力。

Linux 进程 I/O 连续采样中缓存写入与实际磁盘写入的前后对照

三组对照能快速缩小范围

rchar 很大,read_bytes 很小

优先考虑页缓存命中、重复读取同一热文件,或读取来自内存文件系统的内容。此时先看进程打开了哪些文件,再用设备级指标确认磁盘是否繁忙,不要直接扩大磁盘带宽。

wchar 很大,write_bytes 增长缓慢

这通常是写入先被缓存。要继续观察回写压力、脏页比例和文件系统空间;如果服务有明确的持久化边界,还要核对它是否主动调用了同步语义。这里别把“系统调用已经返回”当成“数据已经落盘”。

write_bytes 持续增长且 cancelled_write_bytes 也增长

检查临时文件、覆盖写和频繁截断。日志组件反复写入后又删除、缓存文件生成后立即替换,都可能让取消写入计数上升。结合 lsof -p $PID 和文件路径,通常能找到具体目录。

排查时别漏掉 PID 生命周期和 I/O 来源

服务重启后 PID 会变化,旧 PID 的累计值不能和新 PID 直接相加。记录采样时间、PID、启动时间与四个核心字段,遇到重启就开启新的一段序列。容器环境还要注意:进程看到的 PID、挂载点和设备统计口径可能与宿主机不同。

如果问题是“整块盘变慢”,还需要同时查看设备级吞吐、队列和延迟;如果问题是“某个进程读写异常”,再用 /proc/PID/io、文件描述符和路径定位。两个层级不要混为一个结论。

常见问题

read_bytes 为 0,是不是进程没有读文件?

不一定。读取可能命中页缓存,或者来自内存文件系统;先看 rchar 是否增长,再结合设备指标判断。

write_bytes 能代表数据已经持久化吗?

不能。它描述的是进程相关的块设备写入累计量,不等同于应用完成业务提交或存储设备已经安全持久化。

为什么两个进程的 write_bytes 加起来和磁盘写入对不上?

进程统计与设备统计口径不同,还可能存在内核线程、回写、元数据和文件系统放大;把进程级数据用于归因,把设备级数据用于总量验收。

如何避免把旧 PID 的数据带进新一轮统计?

每次进程启动都记录新的 PID 和启动时间,按相邻采样做差,不要跨重启直接累加。

rchar/wchar 当成“进程请求过多少数据”,把 read_bytes/write_bytes 当成“更接近存储层完成了多少数据”,再用连续采样和设备指标交叉核对,Linux I/O 排查会比只看一个总量可靠得多。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>