每个文件的Linux IO监控?

ker*_*att 33 linux centos

我对在CentOS 上监控每个文件的磁盘 IO 的实用程序或进程感兴趣。

在 Win2008 上,resmon实用程序允许这种类型的向下钻取,但我发现的 Linux 实用程序都没有这样做(iostat、iotop、dstat、nmon)。

我对监控数据库服务器上的 IO 瓶颈感兴趣。使用 MSSQL,我发现它是一种信息丰富的诊断方法,可以了解哪些文件/文件空间受到的打击最严重。

Ril*_*ndo 21

SystemTap可能是您最好的选择。

iotime.stp示例的输出如下所示:

825946 3364 (NetworkManager) access /sys/class/net/eth0/carrier read: 8190 write: 0
825955 3364 (NetworkManager) iotime /sys/class/net/eth0/carrier time: 9
[...]
117061 2460 (pcscd) access /dev/bus/usb/003/001 read: 43 write: 0
117065 2460 (pcscd) iotime /dev/bus/usb/003/001 time: 7
[...]
3973737 2886 (sendmail) access /proc/loadavg read: 4096 write: 0
3973744 2886 (sendmail) iotime /proc/loadavg time: 11
Run Code Online (Sandbox Code Playgroud)

缺点(除了学习曲线)是您需要安装kernel-debug,这在生产系统上可能是不可能的。但是,您可以借助交叉检测,在开发系统上编译模块,然后在生产系统上运行该.ko

或者,如果您不耐烦,请查看初学者指南中的第 4 章“有用的 SystemTap 脚本”。


Cri*_*itu 19

SystemTap *脚本:

#!/usr/bin/env stap
#
# Monitor the I/O of a program.
#
# Usage:
#   ./monitor-io.stp name-of-the-program

global program_name = @1

probe begin {
  printf("%5s %1s %6s %7s %s\n",
         "PID", "D", "BYTES", "us", "FILE")
}

probe vfs.read.return, vfs.write.return {
  # skip other programs
  if (execname() != program_name)
    next

  if (devname=="N/A")
    next

  time_delta = gettimeofday_us() - @entry(gettimeofday_us())
  direction = name == "vfs.read" ? "R" : "W"

  # If you want only the filename, use
  // filename = kernel_string($file->f_path->dentry->d_name->name)
  # If you want only the path from the mountpoint, use
  // filename = devname . "," . reverse_path_walk($file->f_path->dentry)
  # If you want the full path, use
  filename = task_dentry_path(task_current(),
                              $file->f_path->dentry,
                              $file->f_path->mnt)

  printf("%5d %1s %6d %7d %s\n",
         pid(), direction, $return, time_delta, filename)
}
Run Code Online (Sandbox Code Playgroud)

输出如下所示:

[root@sl6 ~]# ./monitor-io.stp cat
PID D  BYTES      us FILE
3117 R    224       2 /lib/ld-2.12.so
3117 R    512       3 /lib/libc-2.12.so
3117 R  17989     700 /usr/share/doc/grub-0.97/COPYING
3117 R      0       3 /usr/share/doc/grub-0.97/COPYING
Run Code Online (Sandbox Code Playgroud)

或者,如果您选择仅显示来自挂载点的路径:

[root@f19 ~]# ./monitor-io.stp cat
  PID D  BYTES      us FILE
26207 R    392       4 vda3,usr/lib64/ld-2.17.so
26207 R    832       3 vda3,usr/lib64/libc-2.17.so
26207 R   1758       4 vda3,etc/passwd
26207 R      0       1 vda3,etc/passwd
26208 R    392       3 vda3,usr/lib64/ld-2.17.so
26208 R    832       3 vda3,usr/lib64/libc-2.17.so
26208 R  35147      16 vdb7,ciupicri/doc/grub2-2.00/COPYING
26208 R      0       2 vdb7,ciupicri/doc/grub2-2.00/COPYING

[root@f19 ~]# mount | grep -E '(vda3|vdb7)'
/dev/vda3 on / type ext4 (rw,relatime,seclabel,data=ordered)
/dev/vdb7 on /mnt/mnt1/mnt11/data type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
Run Code Online (Sandbox Code Playgroud)

限制/错误:

  • 基于mmap的 I/O 不显示,因为devname"N/A"
  • tmpfs 上的文件不显示,因为devname"N/A"
  • 读取是来自缓存还是写入缓冲区都没有关系

Matthew Ife程序的结果:

  • 对于mmaptest私有:

     PID D  BYTES      us FILE
    3140 R    392       5 vda3,usr/lib64/ld-2.17.so
    3140 R    832       5 vda3,usr/lib64/libc-2.17.so
    3140 W     23       9 N/A,3
    3140 W     23       4 N/A,3
    3140 W     17       3 N/A,3
    3140 W     17     118 N/A,3
    3140 W     17     125 N/A,3
    
    Run Code Online (Sandbox Code Playgroud)
  • 对于mmaptest共享:

     PID D  BYTES      us FILE
    3168 R    392       3 vda3,usr/lib64/ld-2.17.so
    3168 R    832       3 vda3,usr/lib64/libc-2.17.so
    3168 W     23       7 N/A,3
    3168 W     23       2 N/A,3
    3168 W     17       2 N/A,3
    3168 W     17      98 N/A,3
    
    Run Code Online (Sandbox Code Playgroud)
  • 对于diotest(直接I/O):

     PID D  BYTES      us FILE
    3178 R    392       2 vda3,usr/lib64/ld-2.17.so
    3178 R    832       3 vda3,usr/lib64/libc-2.17.so
    3178 W     16       6 N/A,3
    3178 W 1048576     509 vda3,var/tmp/test_dio.dat
    3178 R 1048576     244 vda3,var/tmp/test_dio.dat
    3178 W     16      25 N/A,3
    
    Run Code Online (Sandbox Code Playgroud)

* RHEL 6 或同等版本的快速设置说明:yum install systemtapdebuginfo-install kernel

  • 试试这个 mmap:https://gist.github.com/anonymous/7014284 我打赌私有映射没有被测量,但共享映射是.. (2认同)
  • 这是一个直接的 IO 测试:https://gist.github.com/anonymous/7014604 (2认同)

eww*_*ite 9

你实际上想用blktrace这个。请参阅使用 Seekwatcher 和 blktrace 可视化 Linux IO

我会看看我是否可以尽快发布我的示例之一。


编辑:

您没有提到 Linux 的分发,但如果您使用的是类似 RHEL 的系统,那么这对于 Linux 甚至System Tap上的dtrace 脚本来说可能是一个很好的例子。

  • 谢谢,好东西,非常接近重点,但它提供了详细的块层信息,我需要一些适用于 VFS 抽象层的东西。 (2认同)

小智 5

使用 iotop 获取贡献高 IO 的进程的 PID

针对您生成的 PID 运行 strace,您将看到特定进程正在访问哪些文件

strace -f -p $PID -e trace=open,read,write
Run Code Online (Sandbox Code Playgroud)