Linux下的IO监控与分析



 各种IO监视工具在Linux IO 体系结构中的位置 

                                源自 Linux Performance and Tuning Guidelines.pdf

1 系统级IO监控

iostat

  iostat -xdm 1    # 个人习惯

%util         代表磁盘繁忙程度。100% 表示磁盘繁忙, 0%表示磁盘空闲。但是注意,磁盘繁忙不代表磁盘(带宽)利用率高  

argrq-sz    提交给驱动层的IO请求大小,一般不小于4K,不大于max(readahead_kb, max_sectors_kb)

                可用于判断当前的IO模式,一般情况下,尤其是磁盘繁忙时, 越大代表顺序,越小代表随机

svctm        一次IO请求的服务时间,对于单块盘,完全随机读时,基本在7ms左右,既寻道+旋转延迟时间

 

注: 各统计量之间关系

=======================================

%util = ( r/s  +  w/s) * svctm / 1000                        # 队列长度 =  到达率     *  平均服务时间                     
avgrq-sz = ( rMB/s + wMB/s) * 2048 / (r/s  + w/s)    # 2048 为 1M / 512

=======================================

总结:

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

1  距离业务层比较遥远,跟代码中的write,read不对应(由于系统预读 + pagecache + IO调度算法等因素, 也很难对应)

2  是系统级,没办法精确到进程,比如只能告诉你现在磁盘很忙,但是没办法告诉你是谁在忙,在忙什么?

2 进程级IO监控

  iotop 和 pidstat (仅rhel6u系列)

iotop    顾名思义, io版的top

--version #显示版本号
-h, --help #显示帮助信息
-o, --only #显示进程或者线程实际上正在做的I/O,而不是全部的,可以随时切换按o
-b, --batch #运行在非交互式的模式
-n NUM, --iter=NUM #在非交互式模式下,设置显示的次数,
-d SEC, --delay=SEC #设置显示的间隔秒数,支持非整数值
-p PID, --pid=PID #只显示指定PID的信息
-u USER, --user=USER #显示指定的用户的进程的信息
-P, --processes #只显示进程,一般为显示所有的线程
-a, --accumulated #显示从iotop启动后每个线程完成了的IO总数
-k, --kilobytes #以千字节显示
-t, --time #在每一行前添加一个当前的时间

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

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

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

pidstat 参数很多,仅给出几个个人习惯

       pidstat -d  1                  #只显示IO

       pidstat -u -r -d -t 1        # -d IO 信息,

                                           # -r 缺页及内存信息
                                           # -u CPU使用率
                                           # -t 以线程为统计单位
                                           # 1  1秒统计一次

iotop, 很简单,直接敲命令

 

  block_dump, iodump

iotop   和 pidstat 用着很爽,但两者都依赖于/proc/pid/io文件导出的统计信息, 这个对于老一些的内核是没有的,比如rhel5u2

因此只好用以上2个穷人版命令来替代:

echo 1 > /proc/sys/vm/block_dump     # 开启block_dump,此时会把io信息输入到dmesg中

                                                        # 源码: submit_bio@ll_rw_blk.c:3213

watch -n 1 "dmesg -c | grep -oP \"\w+\(\d+\): (WRITE|READ)\" | sort | uniq -c"

                                                         # 不停的dmesg -c

echo 0 > /proc/sys/vm/block_dump      # 不用时关闭

 

也可以使用现成的脚本 iodump, 具体参见 http://code.google.com/p/maatkit/source/browse/trunk/util/iodump?r=5389

 

  iotop.stp

systemtap脚本,一看就知道是iotop命令的穷人复制版,需要安装Systemtap, 默认每隔5秒输出一次信息

stap iotop.stp                                     #  examples/io/iotop.stp

总结

进程级IO监控 ,

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

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

3 业务级IO监控

    ioprofile

    ioprofile 命令本质上是 lsof + strace, 具体下载可见 http://code.google.com/p/maatkit/

    ioprofile 可以回答你以下三个问题:

    1  当前进程某时间内,在业务层面读写了哪些文件(read, write)?

    2  读写次数是多少?(read, write的调用次数)

    3  读写数据量多少?(read, write的byte数)

    假设某个行为会触发程序一次IO动作,例如: "一个页面点击,导致后台读取A,B,C文件"

============================================

    ./io_event   # 假设模拟一次IO行为,读取A文件一次, B文件500次, C文件500次

    ioprofile  -p  `pidof  io_event` -c count   # 读写次数

    ioprofile  -p  `pidof  io_event` -c times   # 读写耗时


    ioprofile  -p  `pidof  io_event` -c sizes    # 读写大小

 

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

    总结:

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

4 文件级IO监控

       文件级IO监控可以配合/补充"业务级和进程级"IO分析

       文件级IO分析,主要针对单个文件, 回答当前哪些进程正在对某个文件进行读写操作.

       1 lsof   或者  ls /proc/pid/fd

       2 inodewatch.stp

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

lsof ../io   #  io目录 当前由 bash 和 lsof 两个进程打开

lsof 命令 只能回答静态的信息, 并且"打开" 并不一定"读取", 对于 cat ,echo这样的命令, 打开和读取都是瞬间的,lsof很难捕捉

可以用 inodewatch.stp 来弥补

stap inodewatch.stp major minor inode      # 主设备号, 辅设备号, 文件inode节点号

stap  inodewatch.stp  0xfd 0x00 523170    # 主设备号, 辅设备号, inode号,可以通过 stat 命令获得

其他IO相关命令

blockdev 系列

=======================================

blockdev --getbsz /dev/sdc1             # 查看sdc1盘的块大小

block blockdev --getra /dev/sdc1      # 查看sdc1盘的预读(readahead_kb)大小

blockdev --setra 256 /dev/sdc1         # 设置sdc1盘的预读(readahead_kb)大小,低版的内核通过/sys设置,有时会失败,不如blockdev靠谱

IO负载高的来源定位

 

前言:

在一般运维工作中经常会遇到这么一个场景,服务器的IO负载很高(iostat中的util),但是无法快速的定位到IO负载的来源进程和来源文件导致无法进行相应的策略来解决问题。

这个现象在MySQL上更为常见,在5.6(performance_schema提供io instrument)之前,我们通常只能猜到是MySQL导致的高IO,但是没法定位具体是哪个文件带来的负载。

例如是ibdata的刷写?还是冷门ibd的随机读取?

本文就将介绍一个比较简单的定位IO高负载的流程。

 

Step1 : iostat 查看IO情况

 iostat -x 1 查看IO情况,从下图可以看到dfa这个磁盘的IO负载较高,接下来我们就来定位具体的负载来源

一般用iostat -x -k -d 1 2(1秒2次)

 Step2: iotop定位负载来源进程

 iotop的本质是一个python脚本,从proc中获取thread的IO信息,进行汇总。

从下图可以看出大部分的IO来源都来自于mysqld进程。因此可以确定dfa的负载来源是数据库


Step3 pt-ioprofile定位负载来源文件

 pt-ioprofile的原理是对某个pid附加一个strace进程进行IO分析。

通过ps aux|grep mysqld 找到 mysqld进程对应的进程号,通过pt-ioprofile查看哪个文件的IO占用时间最多。

默认参数下该工具展示的是IO占用的时间。

 

 对于定位问题更有用的是通过IO的吞吐量来进行定位。使用参数 --cell=sizes,该参数将结果已 B/s 的方式展示出来

 

从上图可以看出IO负载的主要来源是sbtest (sysbench的IO bound OLTP测试)。

并且压力主要集中在读取上。

 

iotop安装:

直接yum安装。

yum install iotop 

在Ubuntu里安装命令是: sudo apt-get install iotop 
安装好之后在终端输入:iotop就可以了 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值