Linux IO 监控与深入分析 - Jamin Zhang

标签: | 发表时间:2018-06-20 20:43 | 作者:
出处:https://jaminzhang.github.io

Linux IO 监控与深入分析

引言

接昨天电话面试,面试官问了系统 IO 怎么分析, 当时第一反应是使用 iotop 看系统上各进程的 IO 读写速度, 然后使用 iostat 看 CPU 的 %iowait 时间占比,(%iowait:CPU等待输入输出完成时间的百分比,%iowait的值过高,表示硬盘存在I/O瓶颈)
但回答并是不很全面,确实,比较久之前写过一篇 Linux iostat 使用, 很久没有在系统上分析 IO 状态了, 所以有好几个分析工具和参数忘记了(说明要熟悉一个知识和技能是需要不断应用和重复学习,熟能生巧很有道理,扯远了,接着说 IO 监控与分析), 然后面试官提示还要看 %util 参数(表示磁盘的繁忙程度),他一说,我确实了也记起来了。这个也是常用要看的参数。
下面我重新查找相关资料并再次学习一下吧,还是要经常在实际工作中多应用才能熟练。

1 系统级 IO 监控

iostat

          [root@xxxx_wan360_game ~]# iostat-xdm1
Linux 2.6.32-358.el6.x86_64(xxxx_wan360_game)12/06/2016 	_x86_64_(8 CPU)Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
xvdep1            0.00     0.00    0.01    1.31     0.00     0.02    31.35     0.00    1.63   0.06   0.01

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
xvdep1            0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
xvdep1            0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
xvdep1            0.00     0.00    0.00    3.00     0.00     0.01     8.00     0.00    0.00   0.00   0.00# iostat 选项-xDisplay extended statistics.  
This option works with post 2.5 kernels since it needs /proc/diskstats file or a mounted sysfs to get the statistics. 
This option may also work with older kernels(e.g. 2.4)onlyifextended statistics are availablein/proc/partitions(the kernel needs to be patchedforthat).-dDisplay the device utilization report.-mDisplay statisticsinmegabytes per second instead of blocks or kilobytes per second.  
Data displayed are valid only with kernels 2.4 and later.
rrqm/s
       The number of read requests merged per second that were queued to the device.
	 排队到设备时,每秒合并的读请求数量

wrqm/s
       The number of write requests merged per second that were queued to the device.
         排队到设备时,每秒合并的写请求数量

r/s
       The number of read requests that were issued to the device per second.
	 每秒发送给设备的读请求数量

w/s
       The number of write requests that were issued to the device per second.
	 每秒发送给设备的的写请求数量

rMB/s
       The number of megabytes read from the device per second.
	 每秒从设备中读取多少 MBs 

wMB/s
       The number of megabytes written to the device per second.
	 每秒往设备中写入多少 MBs


avgrq-sz
	The average size (in sectors) of the requests that were issued to the device.
	分发给设备的请求的平均大小(以扇区为单位)
	磁盘扇区是磁盘的物理属性,它是磁盘设备寻址的最小单元,磁盘扇区大小可以用 fdisk -l 命令查看
	另外,常说的“块”(Block)是文件系统的抽象,不是磁盘本身的属性。
	另外一种说明:
	提交给驱动层的 IO 请求大小,一般不小于 4K,不大于 max(readahead_kb, max_sectors_kb)
	可用于判断当前的 IO 模式,一般情况下,尤其是磁盘繁忙时,越大代表顺序,越小代表随机
	 
avgqu-sz
	The average queue length of the requests that were issued to the device.
	分发给设备的请求的平均队列长度

await
	The average time (in milliseconds) for I/O requests issued to the device to be served. 
	This includes the time spent by the requests in queue and the time spent servicing them.
	分发给设备的 I/O 请求的平均响应时间(单位是毫秒)
	这个时间包含了花在请求在队列中的时间和服务于请求的时间
	另外一种说明:
	每一个 I/O 请求的处理的平均时间(单位是毫秒)。这里可以理解为 I/O 的响应时间。
	一般地,系统 I/O 响应时间应该低于 5ms,如果大于 10ms 就比较大了。

svctm
	The average service time (in milliseconds) for I/O requests that were issued to the device. 
	Warning! Do not trust this field any more. This field will be removed in a future sysstat version.
	分发给设备的 I/O 请求的平均服务时间。(单位是毫秒)
	警告!不要再相信这列值了。这一列将会在一个将来的 sysstat 版本中移除。
	另外一种说明:
	一次 IO 请求的服务时间,对于单块盘,完全随机读时,基本在 7ms 左右,即寻道 + 旋转延迟时间
	
%util
	Percentage of elapsed time during which I/O requests were issued to the device 
	(bandwidth utilization for the device). Device saturation occurs when this value is close to 100%.
	 分发给设备的 I/O 请求的运行时间所占的百分比。(设备的带宽利用率)
	 设备饱和会发生在这个值接近 100%。
	 另外一种说明:
	 代表磁盘繁忙程度。100% 表示磁盘繁忙,0% 表示磁盘空闲。但是注意,磁盘繁忙不代表磁盘(带宽)利用率高。
	 在统计时间内所有处理 I/O 时间,除以总共统计时间。
	 例如,如果统计间隔 1 秒,该设备有 0.8 秒在处理 I/O,而 0.2 秒闲置,那么该设备的 %util = 0.8/1 = 80%,
	 所以该参数暗示了设备的繁忙程度。一般地,如果该参数是 100% 表示设备已经接近满负荷运行了
	 (当然如果是多磁盘,即使 %util 是 100%,因为磁盘的并发能力,所以磁盘使用未必就到了瓶颈)。

%iowait
	Show the percentage of time that the CPU or CPUs were idle during 
	which the system had an outstanding disk I/O request.
	 显示当系统有一个显著的磁盘 I/O 请求期间,CPU 空闲时间的百分比。

总结:
iostat 统计的是通用块层经过合并(rrqm/s, wrqm/s)后,直接向设备提交的 IO 数据,可以反映系统整体的 IO 状况,
但是有以下 2 个缺点:

1. 距离业务层比较遥远,跟代码中的 write,read 不对应(由于系统预读 + PageCache + IO 调度算法等因素,也很难对应)
2. 是系统级,没办法精确到进程,比如只能告诉你现在磁盘很忙,但是没办法告诉你是谁在忙,在忙什么

另一资料的总结:

  • 如果 %iowait 的值过高,表示磁盘存在 I/O 瓶颈。
  • 如果 %util 接近 100%,说明产生的 I/O 请求太多,I/O 系统已经满负荷,该磁盘可能存在瓶颈。
  • 如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间;
  • 如果 await 远大于 svctm,说明 I/O 队列太长,I/O 响应太慢,则需要进行必要优化。
  • 如果 avgqu-sz 比较大,也表示有大量 IO 在等待。

2 进程级 IO 监控

iotop 和 pidstat

  • iotop 顾名思义, IO 版的 top
  • pidstat 顾名思义, 统计进程(pid)的 stat,进程的 stat 自然包括进程的 IO 状况

这两个命令,都可以按进程统计 IO 状况,因此可以回答你以下二个问题:

  1. 当前系统哪些进程在占用 IO,百分比是多少?
  2. 占用 IO 的进程是在读?还是在写?读写量是多少?

pidstat 参数很多,根据需要使用

          [root@xxxx_wan360_game ~]# pidstat-d1# 只显示 IOLinux 2.6.32-358.el6.x86_64(xxxx_wan360_game)12/06/2016 	_x86_64_(8 CPU)05:28:57 PM       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
05:28:58 PM        50      0.00      4.00      0.00  sync_supers
05:28:58 PM       627      0.00      8.00      0.00  flush-202:65
05:28:58 PM      3852      0.00      8.00      0.00  cente_s0001
05:28:58 PM      3860      0.00      4.00      0.00  game_s0001
05:28:58 PM      3864      0.00      4.00      0.00  game_s0001
05:28:58 PM      3868      0.00      4.00      0.00  game_s0001
05:28:58 PM      3876      0.00      4.00      0.00  gate_s0001
05:28:58 PM      3880      0.00      4.00      0.00  gate_s0001

05:28:58 PM       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command

05:28:59 PM       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
05:29:00 PM     23922      0.00     20.00      0.00  filebeat# pidstat -u -r -d -t 1# -u CPU 使用率# -r 缺页及内存信息# -d IO 信息# -t 以线程为统计单位# 1  1 秒统计一次[root@xxxx_wan360_game ~]# pidstat-u-r-d-t1
Linux 2.6.32-358.el6.x86_64(xxxx_wan360_game)12/06/2016 	_x86_64_(8 CPU)05:32:11 PM      TGID       TID    %usr %system  %guest    %CPU   CPU  Command
05:32:12 PM      3856         -    3.74    0.93    0.00    4.67     5  game_s0001
05:32:12 PM         -      3856    4.67    0.93    0.00    5.61     5  |__game_s0001
05:32:12 PM         -      3922    0.93    0.00    0.00    0.93     2  |__game_s0001
05:32:12 PM      3880         -    0.00    0.93    0.00    0.93     3  gate_s0001
05:32:12 PM         -      3908    0.00    0.93    0.00    0.93     3  |__gate_s0001
05:32:12 PM      6832         -    1.87    4.67    0.00    6.54     4  pidstat
05:32:12 PM         -      6832    1.87    4.67    0.00    6.54     4  |__pidstat

05:32:11 PM      TGID       TID  minflt/s  majflt/s     VSZ    RSS   %MEM  Command
05:32:12 PM      6803         -      5.61      0.00    4124    796   0.00  iostat
05:32:12 PM         -      6803      5.61      0.00    4124    796   0.00  |__iostat
05:32:12 PM      6832         -   1321.50      0.00  101432   1280   0.01  pidstat
05:32:12 PM         -      6832   1321.50      0.00  101432   1280   0.01  |__pidstat
05:32:12 PM      8391         -      0.93      0.00   17992   1176   0.01  zabbix_agentd
05:32:12 PM         -      8391      0.93      0.00   17992   1176   0.01  |__zabbix_agentd
05:32:12 PM      8392         -      2.80      0.00   20064   1320   0.01  zabbix_agentd
05:32:12 PM         -      8392      2.80      0.00   20064   1320   0.01  |__zabbix_agentd

05:32:11 PM      TGID       TID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
05:32:12 PM      1894         -      0.00      3.74      0.00  mysqld
05:32:12 PM         -      1923      0.00      3.74      0.00  |__mysqld

总结:

进程级 IO 监控:

  1. 可以回答系统级 IO 监控不能回答的 2 个问题
  2. 距离业务层相对较近(例如,可以统计进程的读写量)

但是也没有办法跟业务层的 read, write 联系在一起,同时颗粒度较粗,没有办法告诉你,当前进程读写了哪些文件?耗时?大小?

3. 业务级 IO 监控

ioprofile

ioprofile 命令本质上是 lsof + strace ioprofile 可以回答你以下三个问题:

  1. 当前进程某时间内,在业务层面读写了哪些文件(read, write)?
  2. 读写次数是多少?(read, write 的调用次数)
  3. 读写数据量多少?(read, write 的 byte 数)

注: ioprofile 仅支持多线程程序,对单线程程序不支持. 对于单线程程序的 IO 业务级分析,strace 足以。

总结: ioprofile 本质上是 strace,因此可以看到 read,write 的调用轨迹,可以做业务层的 IO 分析(mmap 方式无能为力)

4. 文件级 IO 监控

文件级 IO 监控可以配合/补充”业务级和进程级” IO 分析
文件级 IO 分析,主要针对单个文件,回答当前哪些进程正在对某个文件进行读写操作

  1. lsof 或者 ls /proc/pid/fd
  2. inodewatch.stp

lsof 告诉你当前文件由哪些进程打开

          [root@xxxx_wan360_game ~]# lsof ./# 当前目录当前由 bash 和 lsof 进程打开COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
lsof     8932 root  cwd    DIR 202,65     4096 33652737.lsof     8938 root  cwd    DIR 202,65     4096 33652737.bash    16678 root  cwd    DIR 202,65     4096 33652737.

lsof 命令只能回答静态的信息,并且“打开”并不一定“读取”,
对于 cat,echo 这样的命令,打开和读取都是瞬间的,lsof 很难捕捉 可以用 inodewatch.stp 来弥补    

Ref

Linux 下的 IO 监控与分析
使用 iostat 分析 IO 性能
性能优化-分析 IO 瓶颈

相关 [linux io 监控] 推荐:

Linux下的IO监控与分析

- - 乐无线-无线互联网观察
2010年1月27日,据消息人士透露,搜狐以涉嫌盗版名义将优酷网告上法庭,目前此案已经在北京海淀法院立案. 曾传出已经“握手言和”的张朝阳与古永锵,在距离《中国互联网行业版权自律宣言》发布仅一周后,再次点燃了“战火”. Linux下的IO 监控与分析. 近期要在公司内部做个Linux IO方面的培训, 整理下手头的资料给大家分享下.

Linux的IO性能监控工具iostat详解

- - 搜索引擎技术博客
Linux系统出现了性能问题,一般我们可以通过top、iostat、free、vmstat等命令来查看初步定位问题. 其中iostat可以提供更丰富的IO性能状态数据. 参数 -d 表示,显示设备(磁盘)使用状态;-k某些使用block为单位的列强制使用Kilobytes为单位;1 10表示,数据显示每隔1秒刷新一次,共显示10次.

Linux IO 监控与深入分析 - Jamin Zhang

- -
Linux IO 监控与深入分析. 接昨天电话面试,面试官问了系统 IO 怎么分析, 当时第一反应是使用 iotop 看系统上各进程的 IO 读写速度, 然后使用 iostat 看 CPU 的 %iowait 时间占比,(%iowait:CPU等待输入输出完成时间的百分比,%iowait的值过高,表示硬盘存在I/O瓶颈).

linux异步IO浅析

- Sepher - kouu's home
知道异步IO已经很久了,但是直到最近,才真正用它来解决一下实际问题(在一个CPU密集型的应用中,有一些需要处理的数据可能放在磁盘上. 预先知道这些数据的位置,所以预先发起异步IO读请求. 等到真正需要用到这些数据的时候,再等待异步IO完成. 使用了异步IO,在发起IO请求到实际使用数据这段时间内,程序还可以继续做其他事情).

linux AIO (异步IO) 那点事儿

- zffl - CNode社区
这时候进程至少会阻塞10次,而这可能会导致其他的上千个用户请求得不到处理,这当然是不能接受的.. Linux AIO 早就被提上议程,目前比较知名的有 Glibc 的 AIO   与 Kernel Native AIO. 我们用Glibc 的AIO 做个小实验,写一个简单的程序:异步方式读取一个文件,并注册异步回调函数:.

linux标准IO缓冲机制研究

- - 操作系统 - ITeye博客
一、什么是缓存I/O(Buffered I/O). 缓存I/O又被称作标准I/O,大多数文件系统默认I/O操作都是缓存I/O. 在Linux的缓存I/O机制中,操作系统会将I/O的数据缓存在文件系统的页缓存(page cache)中,也就是说,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间.

在Linux进行IO的正确姿势

- - idea's blog
很多C/C++程序虽然在做网络编程, 但大多用别人封装好的库, 对底层不甚了解, 感觉 IO 操作不是很简单吗. 我敢说, 大多数人进行 IO 的姿势都不对, 所谓的 IO, 主要是 read()/write() 两个函数.. 先说错误的 IO 读操作:. 看起来好像很正确的样子, 返回值也判断了, 不仅判断 -1, 还判断 0, 应该姿势正确吧.

Linux系统监控

- - CSDN博客系统运维推荐文章
查看所有的进程和端口使用情况:. 查看nginx并发(连接数)进程数:. 查看当网络连接状态中,已建立连接的数量:. 查看系统tcp连接中各个状态的连接数. 输出每个ip的连接数,以及总的各个状态的连接数. df -hl 查看磁盘使用情况 . df -hl 查看磁盘剩余空间. df -h 查看每个根路径的分区大小.

通过『iostat -dx 1』命令监控IO性能

- Sean Lee - 火丁笔记
网站的很多性能问题最终都会归结到IO头上,所以说理解iostat命令是非常有必要的. 小技巧:你知道iostat是从哪里得到IO相关信息的吗. 使用strace命令能跟踪到答案:. 注:Strace教程:5 simple ways to troubleshoot using Strace. 注:关于diskstats的说明,参见官方文档(主要是其中的field1 ~ field11部分).