Let's Go!

Linux 性能监控分析(二) (转)

上一篇 / 下一篇  2011-12-14 18:41:25 / 个人分类:系统相关&实用技巧



3.1  vmstat

# vmstat 1procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st 0  3 252696   2432    268   7148 3604 2368  3608  2372  288  288  0  0 21 78  1 0  2 253484   2216    228   7104 5368 2976  5372  3036  930  519  0  0  0 100  0 0  1 259252   2616    128   6148 19784 18712 19784 18712 3821 1853  0  1  3 95  1 1  2 260008   2188    144   6824 11824 2584 12664  2584 1347 1174 14  0  0 86  0 2  1 262140   2964    128   5852 24912 17304 24952 17304 4737 2341 86 10  0  0  4 部分参数说明:(1).      swpd,已使用的 SWAP 空间大小,KB 为单位;

(2).      free,可用的物理内存大小,KB 为单位;

(3).      buff,物理内存用来缓存读写操作的 buffer 大小,KB 为单位;

(4).      cache,物理内存用来缓存进程地址空间的 cache 大小,KB 为单位;

(5).      si,数据从 SWAP 读取到 RAM(swap in)的大小,KB 为单位;

(6).      so,数据从 RAM 写到 SWAP(swap out)的大小,KB 为单位;

(7).      bi,磁盘块从文件系统或 SWAP 读取到 RAM(blocks in)的大小,block 为单位;

(8).      bo,磁盘块从 RAM 写到文件系统或 SWAP(blocks out)的大小,block 为单位;

上面是一个频繁读写交换区的例子,可以观察到以下几点:

(1).      物理可用内存 free 基本没什么显著变化,swapd 逐步增加,说明最小可用的内存始终保持在 256MB(物理内存大小) * 10% = 2.56MB 左右,当脏页达到10%的时候(vm.dirty_background_ratio = 10)就开始大量使用 swap;

(2).      buff 稳步减少说明系统知道内存不够了,kwapd 正在从 buff 那里借用部分内存;

(3).      kswapd 持续把脏页面写到 swap 交换区(so),并且从 swapd 逐渐增加看出确实如此。根据上面讲的 kswapd 扫描时检查的三件事,如果页面被修改了,但不是被文件系统修改的,把页面写到 swap,所以这里 swapd 持续增加。

四. IO

       磁盘通常是计算机最慢的子系统,也是最容易出现性能瓶颈的地方,因为磁盘离 CPU 距离最远而且 CPU 访问磁盘要涉及到机械操作,比如转轴、寻轨等。访问硬盘和访问内存之间的速度差别是以数量级来计算的,就像1天和1分钟的差别一样。要监测 IO 性能,有必要了解一下基本原理和 Linux 是如何处理硬盘和内存之间的 IO 的。

4.1 内存页

在第三节Memory中提到了内存和硬盘之间的 IO 是以页为单位来进行的,在 Linux 系统上1页的大小为 4K。可以用以下命令查看系统默认的页面大小:

$ /usr/bin/time -v date

       ...

       Page size (bytes): 4096

       ...

4.2 缺页中断

       Linux 利用虚拟内存极大的扩展了程序地址空间,使得原来物理内存不能容下的程序也可以通过内存和硬盘之间的不断交换(把暂时不用的内存页交换到硬盘,把需要的内存页从硬盘读到内存)来赢得更多的内存,看起来就像物理内存被扩大了一样。事实上这个过程对程序是完全透明的,程序完全不用理会自己哪一部分、什么时候被交换进内存,一切都有内核的虚拟内存管理来完成。当程序启动的时候,Linux 内核首先检查 CPU 的缓存和物理内存,如果数据已经在内存里就忽略,如果数据不在内存里就引起一个缺页中断(Page Fault),然后从硬盘读取缺页,并把缺页缓存到物理内存里。缺页中断可分为主缺页中断(Major Page Fault)和次缺页中断(Minor Page Fault),要从磁盘读取数据而产生的中断是主缺页中断;数据已经被读入内存并被缓存起来,从内存缓存区中而不是直接从硬盘中读取数据而产生的中断是次缺页中断。

       上面的内存缓存区起到了预读硬盘的作用,内核先在物理内存里寻找缺页,没有的话产生次缺页中断从内存缓存里找,如果还没有发现的话就从硬盘读取。很显然,把多余的内存拿出来做成内存缓存区提高了访问速度,这里还有一个命中率的问题,运气好的话如果每次缺页都能从内存缓存区读取的话将会极大提高性能。要提高命中率的一个简单方法就是增大内存缓存区面积,缓存区越大预存的页面就越多,命中率也会越高。

       下面的 time 命令可以用来查看某程序第一次启动的时候产生了多少主缺页中断和次缺页中断:

$ /usr/bin/time -v date        ...        Major (requiring I/O) page faults: 1        Minor (reclaiming a frame) page faults: 260        ... 4.3  File Buffer Cache

       从上面的内存缓存区(也叫文件缓存区 File Buffer Cache)读取页比从硬盘读取页要快得多,所以 Linux 内核希望能尽可能产生次缺页中断(从文件缓存区读),并且能尽可能避免主缺页中断(从硬盘读),这样随着次缺页中断的增多,文件缓存区也逐步增大,直到系统只有少量可用物理内存的时候 Linux 才开始释放一些不用的页。我们运行 Linux 一段时间后会发现虽然系统上运行的程序不多,但是可用内存总是很少,这样给大家造成了 Linux 对内存管理很低效的假象,事实上 Linux 把那些暂时不用的物理内存高效的利用起来做预存(内存缓存区)呢。下面是一台 Sun 服务器上的物理内存和文件缓存区的情况:

$ cat /proc/meminfoMemTotal:      8182776 kBMemFree:       3053808 kBBuffers:        342704 kBCached:        3972748 kB       这台服务器总共有 8GB 物理内存(MemTotal),3GB 左右可用内存(MemFree),343MB 左右用来做磁盘缓存(Buffers),4GB 左右用来做文件缓存区(Cached),可见 Linux 真的用了很多物理内存做 Cache,而且这个缓存区还可以不断增长。

4.4 页面类型

Linux 中内存页面有三种类型:

(1).      Read pages,只读页(或代码页),那些通过主缺页中断从硬盘读取的页面,包括不能修改的静态文件、可执行文件、库文件等。当内核需要它们的时候把它们读到内存中,当内存不足的时候,内核就释放它们到空闲列表,当程序再次需要它们的时候需要通过缺页中断再次读到内存。

(2).      Dirty pages,脏页,指那些在内存中被修改过的数据页,比如文本文件等。这些文件由 pdflush 负责同步到硬盘,内存不足的时候由 kswapd 和 pdflush 把数据写回硬盘并释放内存。

(3).      Anonymous pages,匿名页,那些属于某个进程但是又和任何文件无关联,不能被同步到硬盘上,内存不足的时候由 kswapd 负责将它们写到交换分区并释放内存。

4.5  IO’s Per Second(IOPS)

       每次磁盘 IO 请求都需要一定的时间,和访问内存比起来这个等待时间简直难以忍受。在一台 2001 年的典型 1GHz PC 上,磁盘随机访问一个 word 需要 8,000,000 nanosec = 8 millisec,顺序访问一个 word 需要 200 nanosec;而从内存访问一个 word 只需要 10 nanosec.(数据来自:Teach Yourself Programming in Ten Years)这个硬盘可以提供 125 次 IOPS(1000 ms / 8 ms)。

4.6  顺序 IO 和 随机 IO

       IO 可分为顺序 IO 和 随机 IO 两种,性能监测前需要弄清楚系统偏向顺序 IO 的应用还是随机 IO 应用。

       (1)顺序 IO 是指同时顺序请求大量数据,比如数据库执行大量的查询、流媒体服务等,顺序 IO 可以同时很快的移动大量数据。可以这样来评估 IOPS 的性能,用每秒读写 IO 字节数除以每秒读写 IOPS 数,rkB/s 除以 r/s,wkB/s 除以 w/s. 下面显示的是连续2秒的 IO 情况,可见每次 IO 写的数据是增加的(45060.00 / 99.00 = 455.15 KB per IO,54272.00 / 112.00 = 484.57 KB per IO)。

       相对随机 IO 而言,顺序 IO 更应该重视每次 IO 的吞吐能力(KB per IO):

$ iostat -kx 1avg-cpu:  %user   %nice %system %iowait  %steal   %idle           0.00    0.00    2.50   25.25    0.00   72.25 Device:  rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %utilsdb       24.00 19995.00 29.00 99.00  4228.00 45060.00   770.12    45.01  539.65   7.80  99.80 avg-cpu:  %user   %nice %system %iowait  %steal   %idle           0.00    0.00    1.00   30.67    0.00   68.33 Device:  rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %utilsdb        3.00 12235.00  3.00 112.00   768.00 54272.00   957.22   144.85  576.44   8.70 100.10       (2)随机 IO 是指随机请求数据,其 IO 速度不依赖于数据的大小和排列,依赖于磁盘的每秒能 IO 的次数,比如 Web 服务、Mail 服务等每次请求的数据都很小,随机 IO 每秒同时会有更多的请求数产生,所以磁盘的每秒能 IO 多少次是关键。

$ iostat -kx 1avg-cpu:  %user   %nice %system %iowait  %steal   %idle           1.75    0.00    0.75    0.25    0.00   97.26 Device:  rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %utilsdb        0.00    52.00  0.00 57.00     0.00   436.00    15.30     0.03    0.54   0.23   1.30 avg-cpu:  %user   %nice %system %iowait  %steal   %idle           1.75    0.00    0.75    0.25    0.00   97.24 Device:  rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %utilsdb        0.00    56.44  0.00 66.34     0.00   491.09    14.81     0.04    0.54   0.19   1.29       按照上面的公式得出:436.00 / 57.00 = 7.65 KB per IO,491.09 / 66.34 = 7.40 KB per IO. 与顺序 IO 比较发现,随机 IO 的 KB per IO 小到可以忽略不计,可见对于随机 IO 而言重要的是每秒能 IOPS 的次数,而不是每次 IO 的吞吐能力(KB per IO)。

4.7 SWAP

       当系统没有足够物理内存来应付所有请求的时候就会用到 swap 设备,swap 设备可以是一个文件,也可以是一个磁盘分区。不过要小心的是,使用 swap 的代价非常大。如果系统没有物理内存可用,就会频繁 swapping,如果 swap 设备和程序正要访问的数据在同一个文件系统上,那会碰到严重的 IO 问题,最终导致整个系统迟缓,甚至崩溃。swap 设备和内存之间的 swapping 状况是判断 Linux 系统性能的重要参考,我们已经有很多工具可以用来监测 swap 和 swapping 情况,比如:top、cat /proc/meminfo、vmstat 等:

$ cat /proc/meminfoMemTotal:      8182776 kBMemFree:       2125476 kBBuffers:        347952 kBCached:        4892024 kBSwapCached:        112 kB...SwapTotal:     4096564 kBSwapFree:      4096424 kB... $ vmstat 1procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st 1  2 260008   2188    144   6824 11824 2584 12664  2584 1347 1174 14  0  0 86  0 2  1 262140   2964    128   5852 24912 17304 24952 17304 4737 2341 86 10  0  0五. network

       网络的监测是所有 Linux 子系统里面最复杂的,有太多的因素在里面,比如:延迟、阻塞、冲突、丢包等,更糟的是与 Linux 主机相连的路由器、交换机、无线信号都会影响到整体网络并且很难判断是因为 Linux 网络子系统的问题还是别的设备的问题,增加了监测和判断的复杂度。现在我们使用的所有网卡都称为自适应网卡,意思是说能根据网络上的不同网络设备导致的不同网络速度和工作模式进行自动调整。我们可以通过 ethtool 工具来查看网卡的配置和工作模式:

# /sbin/ethtool eth0Settings for eth0:        Supported ports: [ TP ]        Supported link modes:   10baseT/Half 10baseT/Full                                100baseT/Half 100baseT/Full                                1000baseT/Half 1000baseT/Full        Supports auto-negotiation: Yes        Advertised link modes:  10baseT/Half 10baseT/Full                                100baseT/Half 100baseT/Full                                1000baseT/Half 1000baseT/Full        Advertised auto-negotiation: Yes        Speed: 100Mb/s        Duplex: Full        Port: Twisted Pair        PHYAD: 1        Transceiver: internal        Auto-negotiation: on        Supports Wake-on: g        Wake-on: g        Current message level: 0x000000ff (255)        Link detected: yes       上面给出的例子说明网卡有 10baseT,100baseT 和 1000baseT 三种选择,目前正自适应为 100baseT(Speed: 100Mb/s)。可以通过 ethtool 工具强制网卡工作在 1000baseT 下:

# /sbin/ethtool -s eth0 speed 1000 duplex full autoneg off 5.1  iptraf

       两台主机之间有网线(或无线)、路由器、交换机等设备,测试两台主机之间的网络性能的一个办法就是在这两个系统之间互发数据并统计结果,看看吞吐量、延迟、速率如何。iptraf 就是一个很好的查看本机网络吞吐量的好工具,支持文字图形界面,很直观。下面图片显示在 100 mbps 速率的网络下这个 Linux 系统的发送传输率有点慢,Outgoing rates 只有 66 mbps.

# iptraf -d eth05.2  netperf

       netperf 运行在 client/server 模式下,比 iptraf 能更多样化的测试终端的吞吐量。先在服务器端启动 netserver:

# netserverStarting netserver at port 12865Starting netserver at hostname 0.0.0.0 port 12865 and family AF_UNSPEC然后在客户端测试服务器,执行一次持续10秒的 TCP 测试:

# netperf -H 172.16.38.36 -l 10TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 172.16.38.36 (172.16.38.36) port 0 AF_INETRecv   Send    SendSocket Socket  Message  ElapsedSize   Size    Size     Time     Throughputbytes  bytes   bytes    secs.    10^6bits/sec    87380  16384  16384    10.32      93.68       从以上输出可以看出,网络吞吐量在 94mbps 左右,对于 100mbps 的网络来说这个性能算的上很不错。上面的测试是在服务器和客户端位于同一个局域网,并且局域网是有线网的情况,你也可以试试不同结构、不同速率的网络,比如:网络之间中间多几个路由器、客户端在 wi-fi、VPN 等情况。

       netperf 还可以通过建立一个 TCP 连接并顺序地发送数据包来测试每秒有多少 TCP 请求和响应。下面的输出显示在 TCP requests 使用 2K 大小,responses 使用 32K 的情况下处理速率为每秒243:

 # netperf -t TCP_RR -H 172.16.38.36 -l 10 -- -r 2048,32768TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 172.16.38.36 (172.16.38.36) port 0 AF_INETLocal /RemoteSocket Size   Request  Resp.   Elapsed  Trans.Send   Recv   Size     Size    Time     Ratebytes  Bytes  bytes    bytes   secs.    per sec    16384  87380  2048     32768   10.00     243.0316384  87380 5.3  iperf

       iperf 和 netperf 运行方式类似,也是 server/client 模式,先在服务器端启动 iperf:

# iperf -s -D------------------------------------------------------------Server listening on TCP port 5001TCP window size: 85.3 KByte (default)------------------------------------------------------------Running Iperf Server as a daemonThe Iperf daemon process ID : 5695       然后在客户端对服务器进行测试,客户端先连接到服务器端(172.16.38.36),并在30秒内每隔5秒对服务器和客户端之间的网络进行一次带宽测试和采样:

# iperf -c 172.16.38.36 -t 30 -i 5------------------------------------------------------------Client connecting to 172.16.38.36, TCP port 5001TCP window size: 16.0 KByte (default)------------------------------------------------------------[  3] local 172.16.39.100 port 49515 connected with 172.16.38.36 port 5001[ ID] Interval       Transfer     Bandwidth[  3]  0.0- 5.0 sec  58.8 MBytes  98.6 Mbits/sec[ ID] Interval       Transfer     Bandwidth[  3]  5.0-10.0 sec  55.0 MBytes  92.3 Mbits/sec[ ID] Interval       Transfer     Bandwidth[  3] 10.0-15.0 sec  55.1 MBytes  92.4 Mbits/sec[ ID] Interval       Transfer     Bandwidth[  3] 15.0-20.0 sec  55.9 MBytes  93.8 Mbits/sec[ ID] Interval       Transfer     Bandwidth[  3] 20.0-25.0 sec  55.4 MBytes  92.9 Mbits/sec[ ID] Interval       Transfer     Bandwidth[  3] 25.0-30.0 sec  55.3 MBytes  92.8 Mbits/sec[ ID] Interval       Transfer     Bandwidth[  3]  0.0-30.0 sec    335 MBytes  93.7 Mbits/sec 5.4  tcpdump 和 tcptrace

       tcmdump 和 tcptrace 提供了一种更细致的分析方法,先用 tcpdump 按要求捕获数据包把结果输出到某一文件,然后再用 tcptrace 分析其文件格式。这个工具组合可以提供一些难以用其他工具发现的信息:

# /usr/sbin/tcpdump -w network.dmptcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes511942 packets captured511942 packets received by filter0 packets dropped by kernel # tcptrace network.dmp1 arg remaining, starting with 'network.dmp'Ostermann's tcptrace -- version 6.6.7 -- Thu Nov  4, 2004 511677 packets seen, 511487 TCP packets tracedelapsed wallclock time: 0:00:00.510291, 1002714 pkts/sec analyzedtrace file elapsed time: 0:02:35.836372TCP connection info:  1: zaber:54581 - boulder:111 (a2b)                   6>    5<  (complete)  2: zaber:833 - boulder:32774 (c2d)                   6>    5<  (complete)  3: zaber:pcanywherestat - 172.16.39.5:53086 (e2f)    2>    3<  4: zaber:716 - boulder:2049 (g2h)                  347>  257<  5: 172.16.39.100:58029 - zaber:12865 (i2j)           7>    5<  (complete)  6: 172.16.39.100:47592 - zaber:36814 (k2l)        255380> 255378<  (reset)  7: breakpoint:45510 - zaber:7012 (m2n)               9>    5<  (complete)  8: zaber:35813 - boulder:111 (o2p)                   6>    5<  (complete)  9: zaber:837 - boulder:32774 (q2r)                   6>    5<  (complete) 10: breakpoint:45511 - zaber:7012 (s2t)               9>    5<  (complete) 11: zaber:59362 - boulder:111 (u2v)                   6>    5<  (complete) 12: zaber:841 - boulder:32774 (w2x)                   6>    5<  (complete) 13: breakpoint:45512 - zaber:7012 (y2z)               9>    5<  (complete)       tcptrace 功能很强大,还可以通过过滤和布尔表达式来找出有问题的连接,比如,找出转播大于100 segments 的连接:

# tcptrace -f'rexmit_segs>100' network.dmp如果发现连接 #10 有问题,可以查看关于这个连接的其他信息:

# tcptrace -o10 network.dmp下面的命令使用 tcptrace 的 slice 模式,程序自动在当前目录创建了一个 slice.dat 文件,这个文件包含了每隔15秒的转播信息:

# tcptrace -xslice network.dmp # cat slice.datdate                segs    bytes  rexsegs rexbytes      new   active--------------- -------- -------- -------- -------- -------- --------16:58:50.244708    85055  4513418        0        0        6        616:59:05.244708   110921  5882896        0        0        0        216:59:20.244708   126107  6697827        0        0        1        316:59:35.244708   151719  8043597        0        0        0        216:59:50.244708    37296  1980557        0        0        0        317:00:05.244708       67     8828        0        0        2        317:00:20.244708      149    22053        0        0        1        217:00:35.244708       30     4080        0        0        0        117:00:50.244708       39     5688        0        0        0        117:01:05.244708       67     8828        0        0        2        317:01:11.081080       37     4121        0        0        1        3

详细出处参考:http://www.jb51.net/LINUXjishu/34607.html



TAG:

 

评分:0

我来说两句

Open Toolbar