每个文件的Linux IO监控?


29

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

在Win2008上,resmon实用程序允许这种类型的钻取,但是我发现没有一个Linux实用程序可以执行此操作(iostat,iotop,dstat,nmon)。

我对监视数据库服务器上的IO瓶颈感兴趣。使用MSSQL,我发现它是一种信息丰富的诊断程序,可以知道哪些文件/文件空间受到的打击最大。


2
也许Linux性能分析和工具:SCren 1x上的Brendan Gregg演讲可以为您提供帮助;参见幻灯片72/115。
Cristian Ciupitu

1
如果可能的话,请注意大多数文件都映射到页面缓存中,因此根据页面缓存中的字节数和磁盘上的字节数,您的号码可能会遍地开花。
马修·伊夫

@马特,但有一个有效的答案!
ewwhite

Answers:


18

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

缺点(除了学习曲线之外)是,您将需要安装kernel-debug,这在生产系统上可能是不可能的。但是,您可以求助于跨仪器,其中您可以在开发系统上编译模块,然后在生产系统上运行该.ko

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


17

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)
}

输出看起来像这样:

[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

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

[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)

局限性/错误:

  • mmap的基于I / O并没有显示出来,因为devnameIS"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
    
  • 对于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
    
  • 对于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
    

* RHEL 6或同等功能的快速设置说明:yum install systemtap以及debuginfo-install kernel


那就是一些相当令人印象深刻的系统点击。多功能性的绝佳证明。
马修·伊夫

这会衡量直接I / O和异步I / O吗?(使用io_submit,而不是posix)
Matthew Ife

@Mlfe:谢谢!附带说明,在编写脚本时,我设法在pv中发现了一个小错误,而在SystemTap(task_dentry_path)中发现了一个小错误:-)我不知道该I / O,但是如果您给我一个命令或一个示例程序。例如,我使用Python测试mmap。dd iflag=direct oflag=direct出现。
克里斯蒂安·丘皮图

2
:尝试此MMAP gist.github.com/anonymous/7014284我打赌私人映射不计量的,但共享的有..
马修伊费

2
这是一个直接的IO测试:gist.github.com/anonymous/7014604
Matthew Ife

9

您实际上想为此使用blktrace。请参阅使用Seekwatcher和blktrace可视化Linux IO

我将看看是否可以很快发布我的示例之一。


编辑:

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


2
谢谢,很好,很关键,但是它提供了详细的块层信息,我需要在VFS抽象层上工作的东西。
GioMac

我开始尝试一些systemtap脚本来运行它。我失败了,因为服务器崩溃了。我可以在Solaris的Dtrace上获得此信息。我今天将尝试使用Linux。
ewwhite

4

我知道的唯一可以按文件监视I / O活动的工具是inotifywatch。它是inotify-tools包装的一部分。不幸的是,它只为您提供操作计数。


4

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

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

strace -f -p $PID -e trace=open,read,write

strace将提供有关系统调用和访问的文件的信息,将很难解析并获得使用情况的统计信息……
GioMac

1
以为我会尝试的。它生成大量数据。并在按Ctrl + C时可能会使进程崩溃。这似乎很危险。
马特


2

我认为您可能会问错问题。如果您正在寻找I / O瓶颈,那么查看磁盘上正在发生的事情可能同样重要。db因执行随机I / O而臭名昭著,这会显着降低吞吐量,尤其是当您只有几个主轴时。

可能更有趣的是查看磁盘本身是否等待时间长。您可以通过命令“ collectl -sD”使用collectl进行此操作,该命令将显示各个磁盘的性能统计信息。是--home可以将其变成类似top的实用程序。如果涉及大量磁盘,请通过colmux运行它:colmux -command“ -sD”,即使在多个系统上,它也可以让您按选择的列进行排序。


从磁盘的角度来看,我并不反对。我可以从中了解到什么是数据库文件空间用于对数据,索引,日志等进行分区,但是在资源有限时将其安装在共享磁盘上(例如开发服务器)。理想情况下,这些文件空间中的每个文件空间都应位于单独的卷上,因此从磁盘角度来看IO就足够了-这很可能就是为什么所有监视实用程序都是磁盘而不是基于文件的原因。
kermatt 2011年

这是正确的问题;目标是试图找出“所有I / O都发生在哪个表上?”,在大多数数据库中,一个表是一个或多个文件。任何磁盘最终都会带有许多文件,确定哪些是热点是有用的数据库调整输入。
格雷格·史密斯


0

也许 的inotify将解决解决这个问题。

inotify API提供了一种监视文件系统事件的机制.Inotify可用于监视单个文件或监视目录。监视目录时,inotify将返回目录本身以及目录中文件的事件。

使用inotify监视文件系统活动

引用化


这可能会提供对文件的调用,但是却几乎无助于发现pid是做什么的,写入的大小,花费的时间和时间。
马修·伊夫

该问题并未询问该过程(可以通过其他方式发现该过程lsof
Gert van den Berg

0

尽管这里的答案中有很多不错的信息,但我想知道它是否真的适用?

如果您要谈论不断写入的10 GB的文件,那么除非它们是不断添加的日志文件或类似文件(在这种情况下只是监视文件大小),否则很有可能是文件被mmap了。 。如果是这样,那么最好的答案可能是您应该停止寻找大多数解决方案。然后,对于任何其他提议的解决方案,您首先要问的是“它是否可以与mmap一起使用”,因为大多数情况下它们不会。但是,您可以将问题变成监视块设备而不是监视文件。

当程序从mmap文件中请求页面时,它只是引用虚拟内存中的位置。该页面可能已经或可能尚未在内存中。如果不是,则生成页面错误,从而触发页面从磁盘加载,但是这发生在虚拟内存系统内,这不容易与特定的应用程序进程或特定的文件绑定。同样,当您的应用程序根据标志更新mmap页面时,可能不会触发立即写入磁盘,并且在某些情况下可能根本不会进入磁盘(尽管这些情况并非您感兴趣)在)。

我认为,针对mmap文件最好的做法是将每个感兴趣的文件放在单独的设备上,并使用设备统计信息收集使用情况信息。您可以为此使用lvm分区。绑定安装不会起作用,因为它不会创建新的块设备。

将文件放在单独的块设备上后,您可以从/ sys / block / *或/ proc / diskstats获取统计信息

将此功能引入生产服务器可能会破坏性很大,但也许您可以使用它。

如果未映射文件,则可以,您可以在此处选择其他解决方案之一。


请仔细阅读,我不需要块级别​​的统计信息:)
GioMac

是的,但是对于映射文件来说,您所要求的统计信息是不可能的,因此,如果您遇到这种情况,则可以通过一种方法来获取有关文件的统计信息,方法是每台设备使用一个文件并读取设备统计信息。
mc0e 2013年



-2

我认为iotop是Linux上识别IO瓶颈的最佳工具之一。


3
-1 iotop不监视每个文件,而是按进程运行
dyasny 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.