性能分析工具【转】

Linux Performance Analysis and Tools(Linux性能分析和工具)

分类:

目录(?)[+]html

摘自:http://my.oschina.NET/greki/blog/336429python

首先来看一张mysql

图:linux

上面这张神同样的图出自国外一个Lead Performance Engineer(Brendan Gregg)的一次分享,几乎涵盖了一个系统的方方面面,任何人,若是没有完善的计算系统知识,网络知识和操做系统的知识,这张图中列出的工具,是不可能所有掌握的。ios

出于本人对Linux系统的极大兴趣,以及对底层知识的强烈渴望,并做为检验本身基础知识的一个指标,我决定将这里的全部工具学习一遍(时间不限),这篇文章将做为我学习这些工具的学习笔记。尽可能组织得方便本身往后查阅,并但愿对别人也有必定帮助。git

这里全部的工具,均可以经过man 得到它的帮助文档,这里只介绍一些常规用法。程序员

注意:文中全部的interval都是指收集数据的间隔时间,times是指采样次数。例如github

vmstat interval times

将命令中的interval和times替换成数字:sql

vmstat 3 5

上面语句的意思就是每3秒中输出一次内存统计数据,共输出5次。数据库

Tools: Basic & Intermediate

  1. uptime
  2. top
  3. htop
  4. mpstat
  5. iostat
  6. vmstat
  7. dstat
  8. netstat
  9. strace
  10. iotop
  11. pidstat
  12. ps
  13. lsof

vmstat

咱们先看一个vmstat 的例子。用下面的命令让它每5秒中打印一个报告。

 

能够用ctrl+c中止vmstat。vmstat的常规用法是vmstat interval times,即每隔interval秒采 样一次,共采样times次,若是省略times,则一直采集数据到用户手动中止。

第一行的值是显示了自系统启动以来的平均值,第二行开始展现如今正在发生的状况,接下来的行会显示每5秒的间隔内发生了什么。每一列的含义在头部,以下所示:

  • procs

r这一列显示了多少进程正在等待cpu,b列显示多少进程正在不可中断的休眠(一般意味着它们在等待IO ,例如磁盘,网络,用户输入,等等)。

  • memory

swapd列显示了多少块被换出到了磁盘(页面交换)。剩下的三个列显示了多少块是空闲的(未被使用),多少块正在被用做缓冲区,以及多少正在被用做操做系统的缓存。

  • swap

这些列显示页面交换活动:每秒有多少块正在被换入(从磁盘)和换出(到磁盘)。它们比监控swpd列重要多了。大部分时间咱们但愿看到si 和so 列是0,而且咱们很明确不但愿看到每秒超过10个块。

  • io

这些列显示了多少块从块设备读取(bi)和写出(bo)。这一般反映了硬盘I/O。

  • system

这些列显示了每秒中断(in)和上下文切换(cs)的数量。除非上下文切换超过100 000次或更多,通常不用担忧上下文切换。

  • cpu

这些列显示全部的CPU时间花费在各种操做的百分比,包括执行用户代码(非内核),执行系统代码(内核),空闲以及等待IO。若是正在使用虚拟化,第5列多是st,显示了从虚拟机中"偷走"的百分比。

内存不足的表现:free memory 急剧减小,回收buffer和cache也无济于事,大量使用交换分区(swpd),页面交换(swap)频繁,读写磁盘数量(io)增多,缺页中断(in)增多,上下文切换(cs)次数增多,等待IO的进程数(b)增多,大量CPU时间用于等待IO(wa)。

iostat

如今让咱们转移到iostat 。默认状况下,它显示了与vmstat 相同的CPU 使用信息。咱们一般只对I/O统计感兴趣,因此使用下面的命令只展现扩展的设备统计。

 

与vmstat同样,第一行报告显示的是自系统启动以来的平均值,(一般删掉它节省空间),而后接下来的报告显示了增量的平均值,每一个设备一行。

有多种选项显示和隐藏列。官方文档有点难以理解,所以咱们必须从源码中挖掘真正显示的内容是什么。说明的列信息以下:

为了看懂Linux的磁盘IO指标,先了解一些常见的缩写习惯:rq是request,r是read,w是write,qu是queue,sz是size的,a是average,tm是time,svc是service。

  • rrqm/s 和 wrqm/s

    每秒合并的读和写请求。"合并的"意味着操做系统从队列中拿出多个逻辑请求合并为一个请求到实际磁盘。

  • r/s 和 w/s

    每秒发送到设备的读和写请求数。

  • rsec/s 和 wsec/s

    每秒读和写的扇区数。有些系统也输出为rKB/s和wKB/s ,意味每秒读写的千字节数。(iostat -dkx interval times)

  • avgrq-sz

    请求的扇区数。(读扇区数 + 写扇区数) / (读请求次数 + 写请求次数)

  • avgqu-sz

    在设备队列中等待的请求数。即队列的平均长度。

  • await

    每一个IO请求花费的时间,包括在队列中的等待时间和实际请求(服务)时间。

  • svctm

    实际请求(服务)时间,以毫秒为单位,不包括排队时间。

  • %util

    至少有一个活跃请求所占时间的百分比。更好的说法应该是,服务时间所占的百分比。以上面的输出为例。 一秒中内,读了2.5次,写了1.8次,每次请求的实际请求时间(不包括排队时间)为6.0ms,那么总的时间花费为(2.5+1.8)*6.0ms,即25.8ms,0.0258秒,转换成百分比再四舍五入就获得了util的值2.6%。

    %util: When this figure is consistently approaching above 80% you will need to take any of the following actions -

    • increasing RAM so dependence on disk reduces
    • increasing RAID controller cache so disk dependence decreases
    • increasing number of disks so disk throughput increases (more spindles working parallely)
    • horizontal partitioning

下面这个公式能够计算一个请求在整个请求期间,有多少时间用以等待。当这个值大于50%,说明整个请求期间,花费了更多时间在队列中等待;若是这个数很大,则应该采起相应措施。

  • (await-svctim)/await*100: The percentage of time that IO operations spent waiting in queue in comparison to actually being serviced. If this figure goes above 50% then each IO request is spending more time waiting in queue than being processed. If this ratio skews heavily upwards (in the >75% range) you know that your disk subsystem is not being able to keep up with the IO requests and most IO requests are spending a lot of time waiting in queue. In this scenario you will again need to take any of the actions above

IO瓶颈的症状: 1. %util 很高 2. await 远大于svctm 3. avgqu-sz 比较大

下面解释了iowait的做用,须要注意的是,高速CPU也可能致使iowait取值较大。

  • %iowait: This number shows the % of time the CPU is wasting in waiting for IO. A part of this number can result from network IO, which can be avoided by using an Async IO library. The rest of it is simply an indication of how IO-bound your application is. You can reduce this number by ensuring that disk IO operations take less time, more data is available in RAM, increasing disk throughput by increasing number of disks in a RAID array, using SSD (Check my post on Solid State drives vs Hard Drives) for portions of the data or all of the data etc

上面的解释主要参考《高性能MySQL》和这篇博客

cpu 密集型机器

cpu 密集型服务器的vmstat 输出一般在us 列会有一个很高的值,报告了花费在非内核代码上的cpu 时钟;也可能在sy 列有很高的值,表示系统cpu 利用率,超过20% 就足以使人不安了。在大部分状况下,也会有进程队列排队时间(在r列报告的)。下面是一个列子:

 

若是咱们在同一台及其上观察iostat 的输出(再次剔除显示启动以来平均值的第一行),能够发现磁盘利用率低于50%:

 

这台机器不是IO密集型的,可是依然有至关数量的IO发生,在数据库服务器中这种状况不多见。另外一方面,传统的Web 服务器会消耗掉大量的CPU 资源,可是不多发生IO,因此Web 服务器的输出不会像这个例子。

IO 密集型机器

在IO密集型工做负载下,CPU花费大量时间在等待IO请求完成。这意味着vmstat 会显示不少处理器在非中断休眠(b列)状态,而且在wa 这一列的值很高,下面是个例子:

 

这台机器的iostat 输出显示硬盘一直很忙:

 

%util的值可能由于四舍五入的错误超过100%。什么迹象意味着机器是IO密集的呢?只要有足够的缓冲来服务写请求,即便机器正在作大量的写操做,也可能能够知足,可是却一般意味着硬盘可能会没法知足读请求。这听起来好像违反直觉,可是若是思考读和写的本质,就不会这么认为了:

  • 写请求可以缓冲或同步操做。
  • 读请求就其本质而言都是同步的。固然,程序能够猜想到可能须要某些数据,并异步地提早读取(预读)。不管如何,一般程序在继续工做前必须获得它们须要的数据。这就强制读请求为同步操做:程序必须阻塞直到请求完成。

想一想这种方式:你能够发出一个写请求到缓冲区的某个地方,而后过一会完成。甚至能够每秒发出不少这样的请求。若是缓冲区正确工做,而且有足够的空间,每一个请求均可以很快完成,而且实际上写到物理硬盘是被从新排序后更有效地批量操做的。然而,没有办法对读操做这么作————无论多小或多少的请求,都不可能让硬盘响应说:"这是你的数据,我等一会读它"。这就是为何读须要IO等待是能够理解的缘由。

发生内存交换的机器

一台正在发生内存交换的机器可能在swpd 列有一个很高的值,也可能不高。可是能够看到si 和 so 列有很高的值,这是咱们不但愿看到的。下面是一台内存交换严重的机器的vmstat 输出:

 

空闲的机器

下面是一台空闲机器上的vmstat输出。能够看到idle列显示CPU是100%的空闲。

 

dstat

dstat 显示了cpu使用状况,磁盘io 状况,网络发包状况和换页状况。

我的以为,iostat和vmstat 的输出虽然详细,可是不够直观,不如dstat 好用。并且,dstat输出是彩色的,可读性更强。如今dstat做为我首选的,查看系统状态的工具。

dstat使用时,直接输入命令便可,不用任何参数。也能够经过指定参数来显示更加详细的信息。

dstat -cdlmnpsy

 

iotop

经过iostat和dstat咱们能够知道系统的当前IO负载,可是IO负载具体是由哪一个进程产生的呢?这时候咱们须要的是iotop.

iotop是一个用来监视磁盘I/O使用情况的top类工具,具备与top类似的UI,其中包括PID、用户、I/O、进程等相关信息。 iotop使用Python语言编写而成,要求Python 2.5(及以上版本)和Linux kernel 2.6.20(及以上版本)。使用很是简单,在此不作过多介绍,详细信息参见官网:http://guichaz.free.fr/iotop/

这个命令也能够以非交互的方式使用:

iotop -bod interval

查看每一个进程的IO,也能够经过pidstat命令,不像iotop,且pidstat还不须要root权限。

pidstat -d interval

pidstat

了解系统IO的状况大多数是经过iostat来获取的,这个粒度只能精确到每一个设备。一般咱们会想了 解每一个进程,线程层面发起了多少IO,在Linux 2.6.20以前除了用systemtap这样的工具来实现 是没有其余方法的,由于系统没有暴露这方面的统计。如今能够经过一个名为pidstat的工具, 它的使用方法以下:

pidstat -d interval

此外,pidstat 还能够用以统计CPU使用信息。

pidstat -u interval

统计内存信息:

pidstat -r interval

top

top 命令的汇总区域显示了五个方面的系统性能信息: 1. 负载:时间,登陆用户数,系统平均负载 2. 进程:运行,睡眠,中止,僵尸 3. CPU :用户态,核心态,NICE,空闲,等待IO,中断等 4. 内存:总量,已用,空闲(系统角度),缓冲,缓存 5. 交换分区:总量,已用,空闲

任务区域默认显示:进程ID,有效用户,进程优先级,NICE值,进程使用的虚拟内存,物理内存和共享内存,进程状态,CPU 占用率,内存占用率,累计CPU时间,进程命令行信息。

htop

另外一个更好用的top的替代工具是htop,htop是Linux系统中的一个互动的进程查看器,一个文本模式的应用程序(在控制台或者X终端中),须要ncurses。

 

与Linux传统的top相比,htop更加人性化。它可以让用户交互式操做,支持颜色主题,可横向或纵向滚动浏览进程列表,并支持鼠标操做。

与top相比,htop有如下优势:

  • 能够横向或纵向滚动浏览进程列表,以便看到全部的进程和完整的命令行。
  • 在启动上,比top 更快。
  • 杀进程时不须要输入进程号。
  • htop 支持鼠标操做。

参考资料:Linux下取代top的进程管理工具 htop

mpstat

mpstat 用来统计多核处理器中,每个处理器的使用状况。mpstat使用方法很简单,常见用法以下:

mpstat -P ALL interval times

不出意外,读者执行上面的命令,看不出个因此然来,试试在运行下面这条命令的同时,查看mpstat的输出。

sysbench --test=cpu --cpu-max-prime=20000 run

注意:sysbench是一个基准测试工具,能够用来测试cpu,io,mutex,oltp等。在Debain系统下, 经过下面的命令安装:

sudo apt-get install sysbench

netstat

netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,通常用于检验本机各端口的网络链接状况。

就我本身而言,常用的用法以下:

netstat -npl

上面这条命令能够查看你要打开的端口是否已经打开,以此来做为程序是否已经启动的依据。

netstat 还有不少其余的用法,在《TCP/IP详解》一书中,做者喜欢用netstat命令来打印路由表,使用方法以下:

netstat -rn

其中,flag域的解释以下:

  • U 该路由可用
  • G 该路由是到一个到网关(路由器)。若是没有设置该标志,说明目的地址是直接相连的
  • H 该路由是到一个主机
  • D 该路由是由重定向报文建立
  • M 该路由已被重定向报文修改

netstat 也能够提供系统上的接口信息:

netstat -in

这个命令打印每一个接口的MTU,输入分组数,输入错误,输出分组数,输出错误,冲突以及当前的输出队列的长度。

ps

最最经常使用的用法

ps aux #BSD
ps -ef #linux

ps 参数太多,具体使用方法,请man ps,下面是两种相对经常使用的使用方式。

  • 杀掉某一程序的方法。

    ps aux | grep mysqld | grep -v grep |  awk '{ print $2 }' | xargs kill -9
  • 杀掉僵尸进程:

    ps -eal | awk '{ if ($2 == "Z" ){ print $4}}' | xargs kill -9

strace

用我本身的理解来介绍strace:

咱们写程序,会调用不少库函数,而这些库函数,只是对系统调用的封装,它们最后都会去调用操做系统提供的系统调用,经过系统调用去访问硬件设备。strace的做用就是显示出这些调用关系,让程序员知道调用一个函数,它到底作了些什么事情。固然,strace 远比上面的介绍灵活多变。

下面来看一个例子:

查看mysqld 在linux上加载哪一种配置文件,能够经过运行下面的命令行:

strace -e stat64 mysqld --print-defaults > /dev/null

strace太强大,内容也太多了,我找到一篇比较好的,介绍strace的文章,请点击这里

uptime

uptime是最最最最简单的工具了,可是也有值得讨论的地方,那就是它最后输出的三个数字是怎么得来的,有什么含义?

这三个数字的含义分别是1分钟、5分钟、15分钟内系统的平均负荷,关于这些数字的含义和由来,推荐看阮一峰的文章《理解linux系统负荷这里》。

我想说的是,这三个数字我每天看,时时看,可是我历来不相信它。

此话怎讲呢?我之因此每天看,时时看,是由于我将这三个数字显示到了tmux 的状态栏上,因此,我任什么时候候均可以看到,而不用专门输入uptime这个命令。

为何我不相信它呢,由于这几个数字只能说明有多少线程在等待cpu,若是咱们的一个任务有不少线程,系统负载不是特别高,可是这几个数字会出奇的高,也就是不能彻底相信uptime的缘由。若是不信,能够执行下面这条语句,而后再看看uptime的输出结果。

sysbench --test=mutex --num-threads=1600 --mutex-num=2048                 --mutex-locks=1000000 --mutex-loops=5000 run

运行了5分钟之后,个人电脑上输出以下所示。须要强调的是,这个时候电脑一点不卡,看uptime来判断系统负载,跟听cpu风扇声音判断系统负载同样。只能做为线索,不能做为系统负载很高的依据。

20:32:39 up 10:21,  4 users,  load average: 386.53, 965.37, 418.57

《Linux Performance Analysis and Tools》里面也说了,This is only useful as a clue. Use other tools to investigate!

lsof

lsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以 文件的形式存在,经过文件不只仅能够访问常规数据,还能够访问网络链接和硬件。因此如传输 控制协议(TCP)和用户数据报协议(UDP)套接字等,系统在后台都为该应用程序分配了一个文件描 述符,不管这个文件的本质如何,该文件描述符为应用程序与基础操做系统之间的交互提供了 通用接口。由于应用程序打开文件的描述符列表提供了大量关于这个应用程序自己的信息,所以 经过lsof工具可以查看这个列表对系统监测以及排错将是颇有帮助的。

lsof 的使用方法能够参考这里。这里仅列出几种常见的用法。

  1. 查看文件系统阻塞 lsof /boot

  2. 查看端口号被哪一个进程占用 lsof -i :3306

  3. 查看用户打开哪些文件 lsof -u username

  4. 查看进程打开哪些文件 lsof -p 4838

  5. 查看远程已打开的网络连接 lsof -i @192.168.34.128

参考资料:

  1. Linux经常使用监控命令介绍
  2. 使用lsof查找打开的文件
相关文章
相关标签/搜索