https://jaminzhang.github.io/os/Linux-IO-Monitoring-and-Deep-Analysis/

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 -xdm 1
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 选项 -x Display 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) only if extended statistics are available in /proc/partitions
(the kernel needs to be patched for that). -d Display the device utilization report. -m Display statistics in megabytes 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 -d 1 # 只显示 IO
Linux 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 -t 1
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 监控与深入分析的更多相关文章

  1. Linux中IO监控命令的使用分析

    一篇不错的有关linux io监控命令的介绍和使用. 1.系统级IO监控 iostat iostat -xdm 1    # 个人习惯 %util         代表磁盘繁忙程度.100% 表示磁盘 ...

  2. [转]linux 系统监控、诊断工具之 IO wait

    1.问题: 最近在做日志的实时同步,上线之前是做过单份线上日志压力测试的,消息队列和客户端.本机都没问题,但是没想到上了第二份日志之后,问题来了: 集群中的某台机器 top 看到负载巨高,集群中的机器 ...

  3. Linux下的IO监控与分析

    Linux下的IO监控与分析 近期要在公司内部做个Linux IO方面的培训, 整理下手头的资料给大家分享下 各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performan ...

  4. Linux进程实时IO监控iotop命令详解

    介绍 Linux下的IO统计工具如iostat, nmon等大多数是只能统计到per设备的读写情况, 如果你想知道每个进程是如何使用IO的就比较麻烦. iotop 是一个用来监视磁盘 I/O 使用状况 ...

  5. 【转载】Linux下的IO监控与分析

    近期要在公司内部做个Linux IO方面的培训, 整理下手头的资料给大家分享下 各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performance and Tuning G ...

  6. Linux下的IO监控与分析(转)

    各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performance and Tuning Guidelines.pdf 1 系统级IO监控 iostat iostat -x ...

  7. linux性能监控 -CPU、Memory、IO、Network等指标的讲解

    [操作系统-linux]linux性能监控 -CPU.Memory.IO.Network等指标的讲解(转) 一.CPU 1.良好状态指标 CPU利用率:User Time <= 70%,Syst ...

  8. Linux 服务器监控

    200 ? "200px" : this.width)!important;} --> 标签:iostat/free/top/dstat 概述 文字主要讲述使用linux自带 ...

  9. 【知乎网】Linux IO 多路复用 是什么意思?

    提问一: Linux IO多路复用有 epoll, poll, select,知道epoll性能比其他几者要好.也在网上查了一下这几者的区别,表示没有弄明白. IO多路复用是什么意思,在实际的应用中是 ...

随机推荐

  1. [nowcoder]因数个数和

    链接:https://www.nowcoder.com/acm/contest/158/A 考虑每个数对答案的贡献,所以答案就是$\sum_{i=1}^{n}{\lfloor\frac{n}{i}\r ...

  2. Address already in use: make_sock: could not bind to address [::]:80

    **********************************************************处理办法:# ps -aux | grep httpWarning: bad syn ...

  3. 自己用java实现飞鸽传书 2 - 实现文件传输

    第二步:实现文件传递. 上一步只是从服务端传递了一个字符串到客户端,这次需要对代码进行调整,实现从服务端获取文件,在客户端将文件存入目标地址. 调整后的代码: 服务端: import java.io. ...

  4. nrm npm源管理利器

    nrm npm源管理利器 nrm是管理npm源的一个利器. 有时候我们用npm install 安装依赖时会非常的慢,是官方自身的npm本来就慢,然后我们会尝试安装淘宝的npm或者cnpm,这些安装切 ...

  5. java-给微信推送消息 利用企业微信

    目的:给关注用户推送消息 场景:自动化测试,运维监控,接口访问等报错预警.例如线上接口报错,发送提醒消息 准备工作: 1:注册企业号(为什么不用公众号呢?) 企业号注册 2:常用参数介绍: 1:COR ...

  6. java中的char类型所占空间

    java中统一使用unicode编码,所以每个字符都是2个字节16位.unicode包括中文,所以对String类计算长度的时候,一个中文和一个英文都是一个长度.String voice = &quo ...

  7. Django进阶Model篇007 - 聚集查询和分组查询

    接着前面的例子,举例聚集查询和分组查询例子如下: 1.查询人民邮电出版社出了多少本书 >>> Book.objects.filter(publisher__name='人民邮电出版社 ...

  8. 【Python】循环设计

    转载:作者:Vamei 出处:http://www.cnblogs.com/vamei range() 在Python中,for循环后的in跟随一个序列的话,循环每次使用的序列元素,而不是序列的下标. ...

  9. ionic2常见问题——修改应用图标及添加启动画面(官方命令行工具自动生成)

    1.项目根目录->resources 分别存放应用图标及添加启动画面,替换成自己的图案既可. 2.这样在命令行中重新运行ionic resources ,就能看到应用图标和名字已经被替换了: 3 ...

  10. SQLSERVER store procedure 临时表

    有些时候显示重复数据时,使用: ) 但有些时候表A过大或者逻辑复杂.显示数据时,会造成性能的影响,这时你就可以使用临时表:   ) create table #temp( XXX , XXX) )in ...