我编写了一个简单的test.sh
脚本,它只执行以下操作:while true; do cp ./target-file ./target-file.tmp; done
其中target-file
使用创建dd if=/dev/urandom of=target-file bs=1M count=100
并具有du -h target-file
输出101M target-file
。
我尝试使用 htop 测量该进程的磁盘 IO。我启用了所有这些列(在 htop 中可用:F2-> 选择“列”-> 在右侧滚动到底部):
这是某个时间的示例输出(参见底行):
我清楚几个参数:RD_CHAR
大于WR_CHAR
和RD_SYSC
大于WR_SYSC
。从逻辑上讲,为了cp
工作,它必须首先读取文件,然后写入它。所以这是有道理的。
然而,DISK_READ
是一致的0.00 B/s
,并且IO_RBYTES
远小于IO_WBYTES
。显然,假设这意味着进程每秒不读取任何字节是不正确的。或者假设它写入的信息比读取的信息多也是不正确的。
问题:如何从逻辑上理解IO_RBYTES
和的这些非常低的报告值DISK_READ
?
答案1
/proc/$pid/io
您可以在此处找到这些字段的记录:https://man7.org/linux/man-pages/man5/proc.5.html
rchar:读取的字符
数此任务导致从存储中读取的字节数。这只是该进程传递给 read(2) 和类似系统调用的字节总和。它包括终端 I/O 等内容,并且不受是否需要实际物理磁盘 I/O 的影响(读取可能已从页面缓存得到满足)。wchar:写入的
字符数 该任务已导致或应导致写入磁盘的字节数。与 rchar 类似的警告也适用于此。read_bytes: bytes read
尝试计算此过程真正导致从存储层获取的字节数。这对于块支持的文件系统来说是准确的。write_bytes:写入的字节数
尝试计算此过程导致发送到存储层的字节数。
这些定义中有一些关键的微妙之处。
我清楚几个参数:RD_CHAR大于WR_CHAR,RD_SYSC大于WR_SYSC。从逻辑上讲,要使 cp 工作,它必须先读取文件,然后写入文件。所以这是有道理的。
是的,这是正确的,但还有更多内容。rchar
和指标wchar
包括所有读取和写入,包括 STDIN、STDOUT、STDERR、网络等...
现在您只是使用cp
和dd
,它不会输出那么多,所以在这个特定场景中,它不应该产生太多不同之处。但在处理更复杂的流程时需要注意这一点。
但是,DISK_READ 始终为 0.00 B/s,并且 IO_RBYTES 远小于 IO_WBYTES。显然,假设这意味着进程每秒不读取任何字节是不正确的。
理解这种行为的关键是:
read_bytes: bytes read
尝试计算此过程真正导致从存储层获取的字节数。
在您的情况下,输入数据可能仍在页面缓存中,因此您实际上并没有访问磁盘,而是从内存中读取。但由于您正在写入一个新文件,因此输出会写入磁盘。
Tl;Dr:*char 指标包括进程的所有 I/O,包括磁盘、TTY、网络等。 *bytes 指标仅物理磁盘 I/O。