性能测试监控介绍及其数据分析

1.0 性能监测简介

 

性能调优是找出系统瓶颈并消除这些瓶颈的过程。很多系统管理员认为性能调优仅仅是调整一下内核的参数即可解决问题,事实上情况并不是这样。性能调优是实现操作系统的各个子系统之间的平衡性,这些子系统包括:

* CPU

* Memory

* IO

* Network

 

子系统之间相互依存,任何一个子系统的负载过度都能导致其他子系统出现问题,例如:

大量的page-in IO 请求可能导致内存队列被塞满

网卡的巨量吞吐可能导致CPU资源耗尽

系统尝试保持释放内存队列时可能耗尽CPU资源

来自内存的大量磁盘写入请求可能导致CPU资源和IO通道耗尽

 

性能调优的前提是找出系统瓶颈之所在,尽管问题看似由某个子系统所导致,然而这很可能是另外一个子系统的过载所引起的。

 

1.1 判定应用的类型

    为了明白从何处开始着手调整性能瓶颈,弄清被分析系统的性能表现是首要任务。任何系统的应用常可分为以下两类:

* IO限制型——一个IO限制型的应用需要大量的内存和基础存储设备占用。因其需要大量的数据读写请求,此类应用对CPU和网络需求不高(除非存储系统在网络上)。IO限制型应用使用CPU资源来进行IO操作且常进入睡眠状态。数据库应用常被认为属于此类。

* CPU限制型——一个CPU限制型应用需要大量的CPU资源,来进行批量的处理或大量的计算。大容量web服务,mail服务,以及任何类型的渲染服务都被归到此类。

 

1.2 判定基准信息

    系统的利用率因管理员的期望值和系统的参数值而异,判断一个系统是否有性能问题的唯一途径是弄清楚对系统的期望是神马,需求的性能是神马,应该得到的数据是神马?而为了建立这些信息的唯一途径是为系统建立一个基准。在性能可接受的状态下必须为系统建立统计信息,这样就可以在性能不可接受时进行对比。

在下面的例子中,将对两种状态下的统计信息进行对比:

# vmstat 1 

procs                      memory      swap          io     system         cpu 

 r  b   swpd   free   buff  cache   si   so    bi    bo   in    cs us sy wa id 

 1  0 138592  17932 126272 214244    0    0     1    18  109    19  2  1  1 96 

 0  0 138592  17932 126272 214244    0    0     0     0  105    46  0  1  0 99 

 0  0 138592  17932 126272 214244    0    0     0     0  198    62 40 14  0 45 

 0  0 138592  17932 126272 214244    0    0     0     0  117    49  0  0  0 100 

 0  0 138592  17924 126272 214244    0    0     0   176  220   938  3  4 13 80 

 0  0 138592  17924 126272 214244    0    0     0     0  358  1522  8 17  0 75 

 1  0 138592  17924 126272 214244    0    0     0     0  368  1447  4 24  0 72 

 0  0 138592  17924 126272 214244    0    0     0     0  352  1277  9 12  0 79 

  

# vmstat 1 

procs                      memory      swap          io     system         cpu 

 r  b   swpd   free   buff  cache   si   so    bi    bo   in    cs us sy wa id 

 2  0 145940  17752 118600 215592    0    1     1    18  109    19  2  1  1 96 

 2  0 145940  15856 118604 215652    0    0     0   468  789   108 86 14  0  0 

 3  0 146208  13884 118600 214640    0  360     0   360  498    71 91  9  0  0 

 2  0 146388  13764 118600 213788    0  340     0   340  672    41 87 13  0  0 

 2  0 147092  13788 118600 212452    0  740     0  1324  620    61 92  8  0  0 

 2  0 147360  13848 118600 211580    0  720     0   720  690    41 96  4  0  0 

 2  0 147912  13744 118192 210592    0  720     0   720  605    44 95  5  0  0 

 2  0 148452  13900 118192 209260    0  372     0   372  639    45 81 19  0  0 

 2  0 149132  13692 117824 208412    0  372     0   372  457    47 90 10  0  0 

 

只需要看代表idle时间的最后一列(id)就能发现问题,在基准数据中CPU空闲时间在79%-100%之间,在高负荷状态下系统利用率100%且无空闲。需要考虑的是CPU这块的问题。

 

2.0 安装监测工具

 

    大多*nix系统均自带了很多标准监测命令,也有的是第三方工具:

工具名称

描述

基础安装包

可选安装包

vmstat

多功能

Y

Y

mpstat

CPU性能

N

Y

sar

多功能

N

Y

iostat

磁盘性能

N

Y

netstat

网络性能

Y

Y

dstat

多功能

N

大多数

iptraf

流量监测

N

Y

netperf

网络带宽

N

大多数

ethtool

网卡监测

Y

Y

iperf

网络带宽

N

Y

tcptrace

数据包监测

N

Y

iotop

IO监测

N

Y

 

3.0 CPU介绍

    CPU利用率很大部分取决于试图访问它的资源,内核拥有一个管理两种资源的调度器:

线程(单或多)和中断。调度器给予不同资源以不同的优先级,以下由优先级从高到低:

中断——设备通知内核它们处理完成。例如网卡发送一个数据包或硬盘驱动器提供一次IO请求

内核(系统)进程——所有的内核进程都在此级别的优先级进行处理

用户进程——通常被称为“用户空间”,所有应用软件运行在用户空间,拥有最低的优先级

 

为了弄明白内核是如何管理不同的资源的,几个关键概念需要提及一下:context switchesrun queuesutilization

 

3.1 Context Switches(上下文切换)

    大多数处理器在同一时间只能处理一个进程或线程,多线程处理器可同时处理n个线程。然而,linux内核把多核处理器的各个核心当做独立核心。例如,内核把一个双核的处理当做两个独立处理器。

一个标准的内核可同时处理5050000个进程,在只有一颗CPU的情况下,内核必须调度和平衡这些进程和线程。每个线程在处理器上都拥有一个时间分配单元,当一个线程超过自己的时间单元或被更高优先级的程序抢占时,此线程及被传回队列而此时更高优先级的程序将在处理器上执行。这种线程间的切换操作即是上下文切换。

 

3.2 运行队列

    每个CPU维持着一个线程的运行队列,理论上,调度器应该是不断地运行和执行线程。线程要么处于睡眠状态,要么处于可运行状态。假如CPU子系统处于高负载状态,那么内核调度器罢工是有可能的,其结果将导致可运行状态的进程开始阻塞运行队列。运行队列越大,执行进程所花费的时间也越长。

一个很流行的术语叫“load(负载)”经常被用来描述运行队列的状态,系统负载是由正在执行的进程和CPU运行队列中的进程的结合,如果有2个线程正在一个双核系统中执行且4个正在运行队列中,那么负载数即是6,像top等工具可查看过去1,5,15分钟的负载均值。

 

3.3 CPU利用率

    CPU利用率被定义为CPU使用的百分比,CPU如何被利用是衡量一个系统的重要标准。多数性能监测工具把CPU利用分为以下几个类型:

用户时间——CPU花在执行用户空间进程的时间百分比

系统时间——CPU花在执行内核进程和中断的时间百分比

* IO等待——CPU花在等待IO请求完成的时间百分比

* IDLE——CPU的空闲时间百分比

 

4.0 CPU性能监测

    理解CPU的性能状态即是理解中断,运行队列和上下文切换的状态。之前有提到过性能与基准信息有密切关系,但是有些常规的性能预期:

运行队列——每个处理器上的运行队列不应该有超过1-3个排队的线程。例如,一个双核系统不应该有超过6个进行在运行队列里。

* CPU利用率——假如一个CPU满状态负荷,那么以下的平衡关系需要达到:

65%--70%的用户时间

30%--35%的系统时间

0%--5%的空闲时间

上下文切换——上下文切换的数量与CPU的利用率有直接关系。如果CPU处于高负荷状态下那么大量的上下文切换是正常的。

 

linux系统里有很多可以监测以上数据的工具,如vmstattop

 

4.1 vmstat工具的使用

    vmstat工具的低开销使得它可以在一个高负载的系统上持续运行,它有两种工作模式:均值模式和采样模式。采样模式如下:

 

# vmstat 1 

procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- 

 r  b   swpd   free   buff  cache   si   so    bi    bo   in    cs us sy id wa 

 0  0 104300  16800  95328  72200    0    0     5    26    7    14  4  1 95  0 

 0  0 104300  16800  95328  72200    0    0     0    24 1021    64  1  1 98  0 

 0  0 104300  16800  95328  72200    0    0     0     0 1009    59  1  1 98  0 

每个区域的含义:

区域

描述

r

run queue 运行队列中的进程数

b

blocked 等待IO请求完成的阻塞进程数

in

interrupts 正在处理的中断数

cs

context switches 正在发生的上下文切换数

us

user 用户CPU时间百分比

sys

system 内核CPU时间百分比

wa

wait 可运行进程等待IO百分比

id

idle CPU空闲时间百分比

 

4.2 案例分析:CPU持续性利用

# vmstat 1 

procs                      memory      swap          io     system         cpu 

 r  b   swpd   free   buff  cache   si   so    bi    bo   in    cs us sy wa id 

 3  0 206564  15092  80336 176080    0    0     0     0  718    26 81 19  0  0 

 2  0 206564  14772  80336 176120    0    0     0     0  758    23 96  4  0  0 

 1  0 206564  14208  80336 176136    0    0     0     0  820    20 96  4  0  0 

 1  0 206956  13884  79180 175964    0  412     0  2680 1008    80 93  7  0  0 

 2  0 207348  14448  78800 175576    0  412     0   412  763    70 84 16  0  0 

 2  0 207348  15756  78800 175424    0    0     0     0  874    25 89 11  0  0 

 1  0 207348  16368  78800 175596    0    0     0     0  940    24 86 14  0  0 

 1  0 207348  16600  78800 175604    0    0     0     0  929    27 95  3  0  2 

 3  0 207348  16976  78548 175876    0    0     0  2508  969    35 93  7  0  0 

 4  0 207348  16216  78548 175704    0    0     0     0  874    36 93  6  0  1 

 4  0 207348  16424  78548 175776    0    0     0     0  850    26 77 23  0  0 

 2  0 207348  17496  78556 175840    0    0     0     0  736    23 83 17  0  0 

 0  0 207348  17680  78556 175868    0    0     0     0  861    21 91  8  0  1 

可从数据得到如下观察结果:

其拥有很高的中断数(in)和很低的上下文切换数,这说明可能有单个进程在进行大量的硬件资源请求。

用户时间平均在85%以上,说明此进程一直停留在处理器中。

运行队列数刚好达到可接受的上限值,且出现超过上限值的情况。

 

4.3 案例分析:超载调度

    以下示例中内核调度器的上下文切换达到饱和:

# vmstat 1 

procs                      memory      swap          io     system         cpu 

 r  b   swpd   free   buff  cache   si   so    bi    bo   in    cs us sy wa id 

 2  1 207740  98476  81344 180972    0    0  2496     0  900  2883  4 12 57 27 

 0  1 207740  96448  83304 180984    0    0  1968   328  810  2559  8  9 83  0 

 0  1 207740  94404  85348 180984    0    0  2044     0  829  2879  9  6 78  7 

 0  1 207740  92576  87176 180984    0    0  1828     0  689  2088  3  9 78 10 

 2  0 207740  91300  88452 180984    0    0  1276     0  565  2182  7  6 83  4 

 3  1 207740  90124  89628 180984    0    0  1176     0  551  2219  2  7 91  0 

 4  2 207740  89240  90512 180984    0    0   880   520  443   907 22 10 67  0 

 5  3 207740  88056  91680 180984    0    0  1168     0  628  1248 12 11 77  0 

 4  2 207740  86852  92880 180984    0    0  1200     0  654  1505  6  7 87  0 

 6  1 207740  85736  93996 180984    0    0  1116     0  526  1512  5 10 85  0 

 0  1 207740  84844  94888 180984    0    0   892     0  438  1556  6  4 90  0 

可从数据得到如下观察结果:

上下文切换数高于中断数,这表明内核必须花费相当数量的时间来处理上下文切换进程。

大量的上下文切换引起CPU利用的不平衡,明显的事实是大量的IO等待和用户时间的不足。

由于CPUIO等待的限制,运行队列开始阻塞。

 

4.4 mpstat工具的使用

    如果你的系统有多个处理器核心,你就可以使用mpstat工具来监测每个核心。linux内核把一个双核处理器当做2CPU,所以一个拥有2颗双核心的系统将被视为4CPU

# mpstat P ALL 1 

Linux 2.4.21-20.ELsmp (localhost.localdomain)   05/23/2006 

 

05:17:31 PM  CPU   %user   %nice %system   %idle    intr/s 

05:17:32 PM  all    0.00    0.00    3.19   96.53    13.27 

05:17:32 PM    0    0.00    0.00    0.00  100.00      0.00 

05:17:32 PM    1    1.12    0.00   12.73   86.15     13.27 

05:17:32 PM    2    0.00    0.00    0.00  100.00      0.00 

05:17:32 PM    3    0.00    0.00    0.00  100.00      0.00 

 

4.5 案例分析:未过载状态

    下面的案例中有4CPU

# top -d 1 

top - 23:08:53 up  8:34,  3 users,  load average: 0.91, 0.37, 0.13 

Tasks: 190 total,   4 running, 186 sleeping,   0 stopped,   0 zombie 

Cpu(s): 75.2% us,  0.2% sy,  0.0% ni, 24.5% id,  0.0% wa,  0.0% hi,  0.0% 

si 

Mem:   2074736k total,   448684k used,  1626052k free,    73756k buffers 

Swap:  4192956k total,        0k used,  4192956k free,   259044k cached 

 

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                 

15957 nobody    25   0  2776  280  224 R  100  20.5  0:25.48 php                      

15959 mysql     25   0  2256  280  224 R  100  38.2  0:17.78 mysqld                  

15960 apache    25   0  2416  280  224 R  100  15.7  0:11.20 httpd                   

15901 root      16   0  2780 1092  800 R    1  0.1   0:01.59 top                      

1 root      16   0  1780  660  572 S    0  0.0   0:00.64 init                 

 

# mpstat P ALL 1 

Linux 2.4.21-20.ELsmp (localhost.localdomain)   05/23/2006 

 

05:17:31 PM  CPU   %user   %nice %system   %idle    intr/s 

05:17:32 PM  all   81.52    0.00   18.48   21.17    130.58 

05:17:32 PM    0   83.67    0.00   17.35    0.00    115.31 

05:17:32 PM    1   80.61    0.00   19.39    0.00     13.27 

05:17:32 PM    2    0.00    0.00   16.33   84.66      2.01 

05:17:32 PM    3   79.59    0.00   21.43    0.00      0.00 

 

05:17:32 PM  CPU   %user   %nice %system   %idle    intr/s 

05:17:33 PM  all   85.86    0.00   14.14   25.00    116.49 

05:17:33 PM    0   88.66    0.00   12.37    0.00    116.49 

05:17:33 PM    1   80.41    0.00   19.59    0.00      0.00 

05:17:33 PM    2    0.00    0.00    0.00  100.00      0.00 

05:17:33 PM    3   83.51    0.00   16.49    0.00      0.00 

 

05:17:33 PM  CPU   %user   %nice %system   %idle    intr/s 

05:17:34 PM  all   82.74    0.00   17.26   25.00    115.31 

05:17:34 PM    0   85.71    0.00   13.27    0.00    115.31 

05:17:34 PM    1   78.57    0.00   21.43    0.00      0.00 

05:17:34 PM    2    0.00    0.00    0.00  100.00      0.00 

05:17:34 PM    3   92.86    0.00    9.18    0.00      0.00 

 

05:17:34 PM  CPU   %user   %nice %system   %idle    intr/s 

05:17:35 PM  all   87.50    0.00   12.50   25.00    115.31 

05:17:35 PM    0   91.84    0.00    8.16    0.00    114.29 

05:17:35 PM    1   90.82    0.00   10.20    0.00      1.02 

05:17:35 PM    2    0.00    0.00    0.00  100.00      0.00 

05:17:35 PM    3   81.63    0.00   15.31    0.00      0.00 

 

你可以使用ps命令判定哪个进程运行在哪个CPU上:

# while :; do  ps -eo pid,ni,pri,pcpu,psr,comm | grep 'mysqld'; sleep 1; 

done 

  PID  NI PRI %CPU PSR COMMAND 

15775   0  15 86.0   3 mysqld 

  PID  NI PRI %CPU PSR COMMAND 

15775   0  14 94.0   3 mysqld 

  PID  NI PRI %CPU PSR COMMAND 

15775   0  14 96.6   3 mysqld 

  PID  NI PRI %CPU PSR COMMAND 

15775   0  14 98.0   3 mysqld 

  PID  NI PRI %CPU PSR COMMAND 

15775   0  14 98.8   3 mysqld 

  PID  NI PRI %CPU PSR COMMAND 

15775   0  14 99.3   3 mysqld 

 

4.6 小结

    CPU的性能监测包含以下部分:

检查系统运行队列并确保每个核心上不超过3个可运行进程

确保CPU利用率的用户时间和系统时间在70/30之间

CPU花费更多的时间在system mode上时,更有可能是因过载而试图重新调度优先级

运行CPU限制型应用比IO限制型应用更易出现性能瓶颈

5.0 虚拟内存介绍

    虚拟内存是使用磁盘作为RAM的扩充使得可用内存的有效大小得到相应增加。内核会将当前内存中未被使用的块的内容写入硬盘以此来腾出内存空间。当上面的内容再次需要被用到时,它们将被重新读入内存。这些对用户完全透明;在linux下运行的程序只会看到有大量内存空间可用而不会去管它们的一部分时不时的从硬盘读取。当然,硬盘的读写操作速度比内存慢上千倍,所以这个程序的运行速度也不会很快。这个被用作虚拟内存的硬盘空间呗称作交换空间(swap space)。

 

5.1 虚拟内存页

    虚拟内存被分成页,在X86架构下的每个虚拟内存页大小为4KB,当内核由内存向磁盘读写数据时,是以页为单位。内核会把内存页写入swap空间和文件系统。

 

5.2 内核内存分页

    内存分页是一个常见的动作,不能和内存交换相混淆。内存分页是在正常间隔下同步内存中信息至磁盘的过程。随着时间的增长,应用会不断耗尽内存,有时候内核必须扫描内存并回收被分配给其他应用的空闲页面。

 

5.3 页帧回收算法(PFRA

    PFRA负责回收内存。PFRA根据页类型来判断是否被回收,内存页有以下类型:

不可被回收——lockedkernelreserved 被锁、内核、保留页

可交换——无名内存页

可同步——被磁盘同步的页面

可丢弃——静态页,废弃页

除了不可被回收类型外其他均可被PFRA回收。PFRA具有两个主要功能,一个是kswapd内核进程,一个是“Low On Memory Reclaiming”功能。

 

5.4 kswapd

    kswapd守护进程负责确保内存保持可用空闲空间。它监测内核中的pages_highpages_low标记,如果空闲内存空间值小于pages_low值,kswwapd进程开始扫描并尝试每次回收32个页面,如此重复直至空闲内存空间大于pages_high值。

kswapd进程履行以下操作:

假如页面未改变,它将该页面放入free list

假如页面发生改变且被文件系统回写,它将页面内容写入磁盘。

假如页面发生改变且未被文件系统回写(无名页),它将页面内容写入swap设备。

 

5.5 pdflush内核分页

    pdflush守护进程负责同步所有与文件系统相关的页面至磁盘,换句话说,就是当一个文件在内存中发生改变,pdflush守护进程就将其回写进磁盘。

当内存中的脏页面数量超过10%pdflush守护进程开始回写,这个动作与内核的vm.dirty_background_ratio参数值有关。

# sysctl -n vm.dirty_background_ratio

10

 

多数情况下pdflush守护进程与PFRA之间是相互独立的。除了常规的回收动作之外,当内核调用LMR算法时,LMR将强制pdflush进行脏页面回收。

 

5.6 案例分析:大规模写入I/O

    vmstat命令除了报告CPU的情况外还能查看虚拟内存的使用情况,vmstat输出的以下区域与虚拟内存有关:

区域

描述

swapd

当前使用的虚拟内存KB

free

当前空闲的物理内存KB

buff

read()write()使用的物理内存缓冲大小

cache

映射到进程地址空间的物理内存数

so

swap out 从内存到swap写入的大小

si

swap in swap到内存写入的大小

bo

block out 从内存写入磁盘的大小

bi

block in 从磁盘写入内存你的大小

 

以下信息显示一个I/O限制型应用运行时的状态:

# vmstat 3 

 procs           memory              swap          io     system         cpu 

 r  b   swpd   free   buff  cache   si   so    bi    bo   in    cs us sy id wa 

 3  2 809192 261556  79760  886880  416    0  8244   751  426   863 17  3  6 75 

 0  3 809188 194916  79820  952900  307    0 21745  1005 1189  2590 34  6 12 48 

 0  3 809188 162212  79840  988920   95    0 12107     0 1801  2633  2  2  3 94 

 1  3 809268  88756  79924 1061424  260   28 18377   113 1142  1694  3  5  3 88 

 1  2 826284  17608  71240 1144180  100 6140 25839 16380 1528  1179 19  9 12 61 

 2  1 854780  17688  34140 1208980    1 9535 25557 30967 1764  2238 43 13 16 28 

 0  8 867528  17588  32332 1226392   31 4384 16524 27808 1490  1634 41 10  7 43 

 4  2 877372  17596  32372 1227532  213 3281 10912  3337  678   932 33  7  3 57 

 1  2 885980  17800  32408 1239160  204 2892 12347 12681 1033   982 40 12  2 46 

 5  2 900472  17980  32440 1253884   24 4851 17521  4856  934  1730 48 12 13 26 

 1  1 904404  17620  32492 1258928   15 1316  7647 15804  919   978 49  9 17 25 

 4  1 911192  17944  32540 1266724   37 2263 12907  3547  834  1421 47 14 20 20 

 1  1 919292  17876  31824 1275832    1 2745 16327  2747  617  1421 52 11 23 14 

 5  0 925216  17812  25008 1289320   12 1975 12760  3181  772  1254 50 10 21 19 

 0  5 932860  17736  21760 1300280    8 2556 15469  3873  825  1258 49 13 24 15 

通过以上数据可得出以下结果:

大量的数据从磁盘读入内存(bi),因cache值在不断增长

尽管数据正不断消耗内存,空闲空间仍保持在17M左右

* buff值正不断减少,说明kswapd正不断回收内存

* swpd值不断增大,说明kswapd正将脏页面内容写入交换空间(so

 

5.7 小结

    虚拟内存的性能监测包括以下步骤:

当系统利用内存缓存超过磁盘缓存,系统反应速度更快

除在有大量持续的交换空间和磁盘读入动作情况下外,空闲内存空间很少说明cache得到了有效的利用

如果系统报告有持续的交换空间使用,说明内存不足

6.0 I/O监测介绍

    磁盘IO子系统是linux系统里最慢的部分,这是由于其与CPU相比相去甚远,且依赖于物理式工作(转动和检索)。如果将读取磁盘和读取内存所花费的时间转换为分秒,那么他们之间的差距是7天和7分钟,所以linux内核尽量少的进行磁盘操作是至关重要的。以下部分将描述下内核处理数据从磁盘到内存和从内存到磁盘的不同方式。

 

6.1 数据读写——内存页面

    linux内核将磁盘IO分为页面进行操作,大多数linux系统中默认页面大小为4K,即以4K为单位进行磁盘和内存间的读写操作。我们可以使用time命令来查找页面大小:

# /usr/bin/time -v date

......

Page size (bytes): 4096

......

 

6.2 主要页错误(Major Page Faults)和次要页错误(Minor Page Faults

    linux和大多数UNIX系统一样,使用虚拟内存层来映射物理地址空间,这种映射在某种意义上是说当一个进程开始运行,内核仅仅映射其需要的那部分,内核首先会搜索CPU缓存和物理内存,如果没有找到内核则开始一次MPF,一次MPF即是一次对磁盘子系统的请求,它将数据页从磁盘和缓存读入RAM

一旦内存页被映射到高速缓冲区,内核便会试图使用这些页,被称作MnPF,MnPF通过重复使用内存页而缩短了内核时间。

在下面示例中,time命令显示了当一个程序启动的时候产生了多少MPFMnPF,在第一次启动的时候产生了很多MPF

# /usr/bin/time -v evolution

......

Major (requiring I/O) page faults: 163

Minor (reclaiming a frame) page faults: 5918

......

第二次启动的时候MPF消失因为程序已经在内存中:

# /usr/bin/time -v evolution

......

Major (requiring I/O) page faults: 0 

Minor (reclaiming a frame) page faults: 5581

......

 

6.3 文件缓冲区

    文件缓冲区可使内核减少对MPFsMnPFs的使用,随着系统不断地IO操作,缓冲区会随之增大,直至内存空闲空间不足并开始回收,最终结果是系统管理员们开始关心这个事实,但这只是系统正在很好的使用缓冲空间而已。

下面的输入来自/proc/meminfo文件:

# cat /proc/meminfo 

MemTotal: 2075672 kB 

MemFree: 52528 kB 

Buffers: 24596 kB 

Cached: 1766844 kB

......

以上显示系统拥有2G内存,当前有52MB空闲空间,24MBbuffer供应磁盘写操作,1.7GBcache由磁盘读入内存。

内核通过MnPF机制来使用这些东东,光这些数据还不足以说明系统出现瓶颈。

 

6.4 内存页面分类

    在linux内核中有3种内核页:

读取页面——从磁盘读入(MPF)的只读页面,这些页面存在于缓冲区中包括不可改变的静态文件,二进制文件和库文件。内核会因需求而不断地将他们读入内存,如果内存变得不够用,内核会将他们“窃取”至空闲列表,这将导致某个应用通过MPF将它们重新加载至内存。

脏页面——在内存中被内核修改的页面,它们将被pdflush守护进程回写至磁盘,当内存不够用时,kswapd进程也会和pdflush一道进行回写以释放更多内存空间。

无名页面——它们属于某个进程,但是没有任何文件或后端存储与之关联,它们不能被回写进磁盘,当内存不够用时kswapd守护进程会将它们写入交换空间直至RAM释放出来。

 

6.5 数据页面磁盘回写

    应用可能直接调用fsync()sync()系统调用将脏页面回写入磁盘,这些系统调用会直接请求至I/O调度器。如果一个应用不调用它们,则pdflush守护进程会时不时地进行页面回写操作。

 

7.0 监测磁盘I/O

    在一定条件下系统会出现I/O瓶颈,可由很多监测工具监测到,如topvmstatiostatsar等。这些工具输入的信息大致一样,也有不同之处,下面将讨论出现I/O瓶颈的情况。

 

7.1 计算每秒IO

    每一次向磁盘的IO请求都会花费一定时间,这主要是因为磁盘必须旋转,磁头必须检索。磁盘的旋转通常被称为“旋转延迟(rotational delay)”(RD),磁头的移动杯称为“磁盘检索(disk seek)”(DS)。因此每次IO请求的时间由DSRD计算得来,磁盘的RD由驱动气的转速所固定,一RD被为磁盘一转的一半,计算一块10000转磁盘的RD如下:

1. 算出每转的秒数:60/10000转 = 0.006/

2. 转换为毫秒: 0.006*1000毫秒 = 6毫秒

3. 算出RD值: 6/2 = 3毫秒

4. 加上平均检索时间:3+3 = 6毫秒

5. 加上内部转移等待时间: 6+2 = 8毫秒

6. 算出一秒的IO数:1000毫秒/8毫秒 = 125/秒(IOPS

在一块万转硬盘上应用每请求一次IO需要8毫秒,每秒可提供120150次操作。

 

7.2 随机IO和有序IO

    每次IO的数据量与系统的工作负荷相关。系统的负荷分两类:有序和随机。

 

7.2.1 有序IO

    iostat命令可提供IOPS值和每次IO的数据量,有序负荷需要一次有序地读取大量数据,因此每次IO的数据量很大,其性能取决于短时间大数据量的执行能力。

 

计算IOPS能力的方式是用每秒读写数据量除以每秒读写次数:

53040/105 = 505 KB/IO

71152/102 = 697 KB/IO

 

7.2 随机IO

    随机负荷与数据大小关系不大,与磁盘的IOPS值有关,web服务,mail服务一般属于此类,IO请求相对较少,其依赖于一次可执行多少次请求,因此磁盘的IOPS值非常关键。

 

此数据与刚才的数据相比每次IO写入的数据量差异很大:

2640/102 = 23 KB/IO

3176/130 = 24 KB/IO

 

7.3 当虚拟内存终结I/O

    假如系统没有足够的内存供给所有的请求时,并开始使用交换空间,和文件系统IO一样swap的写入也很慢,假如内存严重的不足,那么这可能导致大量的页面涌向swap,假如这个swap空间与要写入的文件处于同一文件系统下,此系统将进入IO争抢,这将导致系统性能直线下降。假如页面无法读或写入磁盘,那么它们将一直停留于内存中,内核会开始尝试释放内存空间,问题是IO通道已经严重阻塞且无法做任何事情,这必将导致系统内核出错并崩溃。

下面的vmstat输出展示了这种情况:

procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- 

 r  b     swpd   free  buff  cache     si  so    bi    bo  in   cs  us  sy  id  wa 

17  0     1250  3248 45820 1488472    30 132   992    0 2437 7657 23  50  0   23 

11  0     1376  3256 45820 1488888    57 245   416    0 2391 7173 10  90  0   0 

12  0     1582  1688 45828 1490228    63 131  1348   76 2432 7315 10  90  0   10 

12  2     3981  1848 45468 1489824   185 56   2300   68 2478 9149 15  12  0   73 

14  2     10385 2400 44484 1489732     0 87   1112   20 2515 11620 0  12   0   88 

14  2     12671 2280 43644 1488816    76 51   1812  204 2546 11407 20  45  0   35 

 

以上数据显示大量的读入内存请求(bi),内存不够,导致数据块不停写入(so)交换空间,交换空间大小不断增长(swpd),同样也出现了大量的IO等待时间(wa),这表明CPU因为IO请求的原因而开始变慢。

 

在上面的例子中,swap设备(/dev/sda1)和文件系统(/dev/sda3)在争抢IO

 

7.4 判定应用IO使用

    iotop命令显示每个进程的IO使用情况,其输出结果与top命令相似,可与iostat命令结合来判断产生IO瓶颈的应用。

在下面的示例中,在同一磁盘上(sda2)既有读操作(r/s)又有写操作(w/s)

# iostat x 1 

 

avg-cpu:  %user   %nice %system %iowait  %steal   %idle 

           7.14    0.00   35.71   57.14    0.00    0.00 

 

Device:       rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util 

sda           0.00     0.00  123.47   25.51   987.76 21951.02   153.97    27.76  224.29   6.85 102.04 

sda1          0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00 

sda2          0.00     0.00  123.47   25.51   987.76 21951.02   153.97    27.76  224.29   6.85 102.04 

 

#iotop -d 5 -P

Total DISK READ: 981.23 K/s | Total DISK WRITE: 21.43 M/s 

  PID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND 

 2574 be/4 root      967.01 K/s    0.00 B/s  0.00 % 39.05 % find / 

   64 be/3 root        0.00 B/s   19.94 M/s  0.00 % 13.09 % smbd -D 

 2533 be/4 dhoch       3.63 K/s    8.72 K/s  0.00 %  1.82 % [kjournald] 

 2442 be/4 root        0.00 B/s    2.91 K/s  0.00 %  0.46 % iostat -x 1 

 2217 be/4 dhoch       0.00 B/s 1488.57 B/s  0.00 %  0.00 % mono /usr~-ior-fd=25 

 1985 be/4 dhoch       0.00 B/s  255.12 K/s  0.00 %  0.00 % smbd -D 

iotopDISK READ DISK WRITE iostatrsec/s wsec/s 相对应。

 

7.5 小结

    I/O性能监测可总结如下:

任何时间出现CPU等待IO,说明磁盘超载。

计算出你的磁盘可维持的IOPS值。

判定你的应用时属于随机磁盘访问型还是有序型。

通过对比等待时间和服务时间即可判断磁盘是否缓慢。

监测交换空间和文件系统坐在分区并确保他们之间不存在争抢IO

 

8.0 网络监测介绍

    网络是所有子系统中最难监测的一个,因为网络比较抽象,在监测时有很多在系统可控制之外的因素如延迟,冲突,拥塞和丢包等对监测产生影响。下面将讨论的是以太网、IPTCP的性能监测。

 

8.1 以太网配置设定

    除非有明确的设定,所有以太网的速度都是自动协商的,这很大程度上是由于历史原因造成的,早些时候一个网络里经常有不同网速和双工模式的网络设备。

大多数企业以太网是100BaseTX1000BaseTX,可以使用ethtool工具来判断一个系统的网速。

    下面的示例中一个拥有100BaseTX网卡的机器工作在10BaseTX下:

# ethtool eth0 

Settings for eth0: 

        Supported ports: [ TP MII ] 

        Supported link modes:   10baseT/Half 10baseT/Full  

                                100baseT/Half 100baseT/Full  

        Supports auto-negotiation: Yes 

        Advertised link modes:  10baseT/Half 10baseT/Full  

                                100baseT/Half 100baseT/Full  

        Advertised auto-negotiation: Yes 

        Speed: 10Mb/s 

        Duplex: Half 

        Port: MII 

        PHYAD: 32 

        Transceiver: internal 

        Auto-negotiation: on 

        Supports Wake-on: pumbg 

        Wake-on: d 

        Current message level: 0x00000007 (7) 

        Link detected: yes 

下面将其强制设定为100BaseTX模式:

# ethtool -s eth0 speed 100 duplex full autoneg off 

# ethtool eth0 

Settings for eth0: 

        Supported ports: [ TP MII ] 

        Supported link modes:   10baseT/Half 10baseT/Full  

                                100baseT/Half 100baseT/Full  

        Supports auto-negotiation: Yes 

        Advertised link modes:  10baseT/Half 10baseT/Full  

                                100baseT/Half 100baseT/Full  

        Advertised auto-negotiation: No 

        Speed: 100Mb/s 

        Duplex: Full 

        Port: MII 

        PHYAD: 32 

        Transceiver: internal 

        Auto-negotiation: off 

        Supports Wake-on: pumbg 

        Wake-on: d 

        Current message level: 0x00000007 (7) 

        Link detected: yes 

 

8.2 网络吞吐量监测

    监测网络吞吐量最好的办法是在两个系统之间发送流量并统计其延迟和速度。

 

8.2.0 使用iptraf监测本地吞吐量

iptraf工具可提供以太网卡的吞吐量情况:

# iptraf -d eth0

 

上面的数据显示被测试系统正以61mbps7.65M)频率发送数据,相比于100mbps网络这有点低。

 

8.2.1 使用netperf监测远端吞吐量

    与iptraf的动态监测不一样的是netperf使用可控方式测试网络,这一点对测试一个客户端到一个高负载服务器之间的吞吐量很有帮助,netperf工具是以C/S模式运行。

首先需要在服务器上运行netperf服务端:

 

server# netserver  

Starting netserver at port 12865 

Starting netserver at hostname 0.0.0.0 port 12865 and family AF_UNSPEC 

 

netperf可以执行多种测试,最基本的是标准测试:

client# netperf -H 192.168.1.215 -l 30 

TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 

192.168.1.230 (192.168.1.230) port 0 AF_INET 

Recv   Send    Send                           

Socket Socket  Message  Elapsed               

Size   Size    Size     Time     Throughput   

bytes  bytes   bytes    secs.    10^6bits/sec   

 

 87380  16384  16384    30.02      89.46

输出显示吞吐量在89mbps左右,服务器和客户端在同一网段。

从一个10跳的54G无线网进行测试只能达到14mbps左右:

client# netperf -H 192.168.1.215 -l 30 

TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 

192.168.1.215 (192.168.1.215) port 0 AF_INET 

Recv   Send    Send                           

Socket Socket  Message  Elapsed               

Size   Size    Size     Time     Throughput   

bytes  bytes   bytes    secs.    10^6bits/sec   

 

 87380  16384  16384    30.10      14.09  

 

50跳距离局域网测试:

# netperf -H 192.168.1.215 -l 30 

TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 

192.168.1.215 (192.168.1.215) port 0 AF_INET 

Recv   Send    Send                           

Socket Socket  Message  Elapsed               

Size   Size    Size     Time     Throughput   

bytes  bytes   bytes    secs.    10^6bits/sec   

 

 87380  16384  16384    30.64       5.05 

 

从外网测试:

# netperf -H litemail.org -p 1500 -l 30 

TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 

litemail.org (72.249.104.148) port 0 AF_INET 

Recv   Send    Send 

Socket Socket  Message  Elapsed 

Size   Size    Size     Time     Throughput 

bytes  bytes   bytes    secs.    10^6bits/sec 

 

 87380  16384  16384    31.58       0.93 

 

通过VPN测试:

# netperf -H 10.0.1.129 -l 30 

TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 

10.0.1.129 (10.0.1.129) port 0 AF_INET 

Recv   Send    Send 

Socket Socket  Message  Elapsed 

Size   Size    Size     Time     Throughput 

bytes  bytes   bytes    secs.    10^6bits/sec 

 

 87380  16384  16384    31.99       0.51 

 

另外一个有用的测试模式是测试TCP请求应答速率,其原理是建立一个TCP连接并发送多个请求:

client# netperf -t TCP_RR -H 192.168.1.230 -l 30 

TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET 

to 192.168.1.230 (192.168.1.230) port 0 AF_INET 

Local /Remote 

Socket Size   Request  Resp.   Elapsed  Trans. 

Send   Recv   Size     Size    Time     Rate          

bytes  Bytes  bytes    bytes   secs.    per sec    

 

16384  87380  1        1       30.00    4453.80    

16384  87380 

 

数据显示网络可支持4453左右的psh/ack 每秒,因为发送包的大小只有1k。下面使用2k的请求和32k的应答:

client# netperf -t TCP_RR -H 192.168.1.230 -l 30 -- -r 2048,32768 

TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 

192.168.1.230 (192.168.1.230) port 0 AF_INET 

Local /Remote 

Socket Size   Request  Resp.   Elapsed  Trans. 

Send   Recv   Size     Size    Time     Rate          

bytes  Bytes  bytes    bytes   secs.    per sec    

 

16384  87380  2048     32768   30.00     222.37    

16384  87380 

 

可以看到速率已经降到222左右。

 

8.2.3 使用iperf测试网络性能

    iperfnetperf相似在两台机器间进行测试,不同之处在于iperf测试更深入,它只有一个可执行文件既可用于服务端又可用于客户端,默认通信端口是5001.

启动服务端(192.168.1.215):

server# iperf -s -D 

Running Iperf Server as a daemon 

The Iperf daemon process ID : 3655 

------------------------------------------------------------ 

Server listening on TCP port 5001 

TCP window size: 85.3 KByte (default) 

------------------------------------------------------------ 

一个满负荷无线网中的客户端进行测试:

client# iperf -c 192.168.1.215 -t 60 -i 5 

------------------------------------------------------------ 

Client connecting to 192.168.1.215, TCP port 5001 

TCP window size: 25.6 KByte (default) 

------------------------------------------------------------ 

[  3] local 192.168.224.150 port 51978 connected with 

192.168.1.215 port 5001 

[ ID] Interval       Transfer     Bandwidth 

[  3]  0.0- 5.0 sec  6.22 MBytes  10.4 Mbits/sec 

[ ID] Interval       Transfer     Bandwidth 

[  3]  5.0-10.0 sec  6.05 MBytes  10.1 Mbits/sec 

[ ID] Interval       Transfer     Bandwidth 

[  3] 10.0-15.0 sec  5.55 MBytes  9.32 Mbits/sec 

[ ID] Interval       Transfer     Bandwidth 

[  3] 15.0-20.0 sec  5.19 MBytes  8.70 Mbits/sec 

[ ID] Interval       Transfer     Bandwidth 

[  3] 20.0-25.0 sec  4.95 MBytes  8.30 Mbits/sec 

[ ID] Interval       Transfer     Bandwidth 

[  3] 25.0-30.0 sec  5.21 MBytes  8.74 Mbits/sec 

[ ID] Interval       Transfer     Bandwidth 

[  3] 30.0-35.0 sec  2.55 MBytes  4.29 Mbits/sec 

[ ID] Interval       Transfer     Bandwidth 

[  3] 35.0-40.0 sec  5.87 MBytes  9.84 Mbits/sec 

[ ID] Interval       Transfer     Bandwidth 

[  3] 40.0-45.0 sec  5.69 MBytes  9.54 Mbits/sec 

[ ID] Interval       Transfer     Bandwidth 

[  3] 45.0-50.0 sec  5.64 MBytes  9.46 Mbits/sec 

[ ID] Interval       Transfer     Bandwidth 

[  3] 50.0-55.0 sec  4.55 MBytes  7.64 Mbits/sec 

[ ID] Interval       Transfer     Bandwidth 

[  3] 55.0-60.0 sec  4.47 MBytes  7.50 Mbits/sec 

[ ID] Interval       Transfer     Bandwidth 

[  3]  0.0-60.0 sec  61.9 MBytes  8.66 Mbits/sec 

 

下面是进行UDP丢包率测试:

# iperf -c 192.168.1.215 -b 10M 

WARNING: option -b implies udp testing 

------------------------------------------------------------ 

Client connecting to 192.168.1.215, UDP port 5001 

Sending 1470 byte datagrams 

UDP buffer size:   107 KByte (default) 

------------------------------------------------------------ 

[  3] local 192.168.224.150 port 33589 connected with 192.168.1.215 port 5001 

[ ID] Interval       Transfer     Bandwidth 

[  3]  0.0-10.0 sec  11.8 MBytes  9.90 Mbits/sec 

[  3] Sent 8420 datagrams 

[  3] Server Report: 

[ ID] Interval       Transfer     Bandwidth       Jitter   Lost/Total Datagrams 

[  3]  0.0-10.0 sec  6.50 MBytes  5.45 Mbits/sec  0.480 ms 3784/ 8419 (45%) 

[  3]  0.0-10.0 sec  1 datagrams received out-of-order 

 

10M的数据只传输了一部分,丢包率在45%左右。

 

8.3 tcptrace进行特定连接测试

    tcptrace工具提供了基于TCP的详细测试信息,基于libpcap文件,它可以监测出有时不太容易抓到的TCP流:

* TCP中继——需要被重新发送的包数量和数据大小

* TCP窗口大小——使用很小的window sizes识别低速度连接

连接的总吞吐量

连接持续性

8.3.1 案例分析

    tcptracelibpcap文件作为输入,不加任何选项执行此工具可显示出包里所有信息,下面的示例中tcptrace处理一个叫bigstuff的包文件:

# tcptrace bigstuff  

1 arg remaining, starting with 'bigstuff' 

Ostermann's tcptrace -- version 6.6.7 -- Thu Nov  4, 2004 

 

146108 packets seen, 145992 TCP packets traced 

elapsed wallclock time: 0:00:01.634065, 89413 pkts/sec analyzed 

trace file elapsed time: 0:09:20.358860 

TCP connection info: 

  1: 192.168.1.60:pcanywherestat - 192.168.1.102:2571 (a2b)       404>  450< 

  2: 192.168.1.60:3356 - ftp.strongmail.net:21 (c2d)               35>   21< 

  3: 192.168.1.60:3825 - ftp.strongmail.net:65023 (e2f)             5>    4<  

(complete) 

  4: 192.168.1.102:1339 - 205.188.8.194:5190 (g2h)                  6>    6< 

5: 192.168.1.102:1490 - cs127.msg.mud.yahoo.com:5050 (i2j)        5>    5< 

  6: py-in-f111.google.com:993 - 192.168.1.102:3785 (k2l)          13>   14< 

。。。 。。。

 

    在上面输出的数据中可以看到每条信息前面都有一个编号,tcptrace最常用的选项是-l-o,用来指定某个具体的连接。下面的示例:

# tcptrace -l -o1 bigstuff  

1 arg remaining, starting with 'bigstuff' 

Ostermann's tcptrace -- version 6.6.7 -- Thu Nov  4, 2004 

 

146108 packets seen, 145992 TCP packets traced 

elapsed wallclock time: 0:00:00.529361, 276008 pkts/sec analyzed 

trace file elapsed time: 0:09:20.358860 

TCP connection info: 

32 TCP connections traced: 

TCP connection 1: 

        host a:        192.168.1.60:pcanywherestat 

        host b:        192.168.1.102:2571 

        complete conn: no       (SYNs: 0)  (FINs: 0) 

        first packet:  Sun Jul 20 15:58:05.472983 2008 

        last packet:   Sun Jul 20 16:00:04.564716 2008 

        elapsed time:  0:01:59.091733 

        total packets: 854 

        filename:      bigstuff 

   a->b:                              b->a: 

     total packets:           404           total packets:           450       

     ack pkts sent:           404           ack pkts sent:           450       

     pure acks sent:           13           pure acks sent:          320       

     sack pkts sent:            0           sack pkts sent:            0       

     dsack pkts sent:           0           dsack pkts sent:           0       

     max sack blks/ack:         0           max sack blks/ack:         0       

     unique bytes sent:     52608           unique bytes sent:     10624       

     actual data pkts:        391           actual data pkts:        130       

     actual data bytes:     52608           actual data bytes:     10624       

     rexmt data pkts:           0           rexmt data pkts:           0       

     rexmt data bytes:          0           rexmt data bytes:          0       

     zwnd probe pkts:           0           zwnd probe pkts:           0       

     zwnd probe bytes:          0           zwnd probe bytes:          0       

     outoforder pkts:           0           outoforder pkts:           0       

     pushed data pkts:        391           pushed data pkts:        130       

     SYN/FIN pkts sent:       0/0           SYN/FIN pkts sent:       0/0       

     urgent data pkts:          0 pkts      urgent data pkts:          0 pkts  

     urgent data bytes:         0 bytes     urgent data bytes:         0 bytes 

     mss requested:             0 bytes     mss requested:             0 bytes 

     max segm size:           560 bytes     max segm size:           176 bytes 

     min segm size:            48 bytes     min segm size:            80 bytes 

     avg segm size:           134 bytes     avg segm size:            81 bytes 

     max win adv:           19584 bytes     max win adv:           65535 bytes 

     min win adv:           19584 bytes     min win adv:           64287 bytes 

     zero win adv:              0 times     zero win adv:              0 times 

     avg win adv:           19584 bytes     avg win adv:           64949 bytes 

     initial window:          160 bytes     initial window:            0 bytes 

     initial window:            2 pkts      initial window:            0 pkts  

     ttl stream length:        NA           ttl stream length:        NA       

     missed data:              NA           missed data:              NA       

     truncated data:        36186 bytes     truncated data:         5164 bytes 

     truncated packets:       391 pkts      truncated packets:       130 pkts  

     data xmit time:      119.092 secs      data xmit time:      116.954 secs  

     idletime max:       441267.1 ms        idletime max:       441506.3 ms    

     throughput:              442 Bps       throughput:               89 Bps   

 

8.3.2 案例分析——计算转发百分比

# tcptrace -f'rexmit_segs>100' bigstuff  

Output filter: ((c_rexmit_segs>100)OR(s_rexmit_segs>100)) 

1 arg remaining, starting with 'bigstuff' 

Ostermann's tcptrace -- version 6.6.7 -- Thu Nov  4, 2004 

 

146108 packets seen, 145992 TCP packets traced 

elapsed wallclock time: 0:00:00.687788, 212431 pkts/sec analyzed 

trace file elapsed time: 0:09:20.358860 

TCP connection info: 

 16: ftp.strongmail.net:65014 - 192.168.1.60:2158 (ae2af) 18695> 9817< 

 

# tcptrace -l -o16 bigstuff  

 arg remaining, starting with 'bigstuff' 

Ostermann's tcptrace -- version 6.6.7 -- Thu Nov  4, 2004 

 

146108 packets seen, 145992 TCP packets traced 

elapsed wallclock time: 0:00:01.355964, 107752 pkts/sec analyzed 

trace file elapsed time: 0:09:20.358860 

TCP connection info: 

32 TCP connections traced: 

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

TCP connection 16: 

        host ae:       ftp.strongmail.net:65014 

        host af:       192.168.1.60:2158 

        complete conn: no       (SYNs: 0)  (FINs: 1) 

        first packet:  Sun Jul 20 16:04:33.257606 2008 

        last packet:   Sun Jul 20 16:07:22.317987 2008 

        elapsed time:  0:02:49.060381 

        total packets: 28512 

        filename:      bigstuff 

   ae->af:                            af->ae: 

.... ....

    unique bytes sent:  25534744           unique bytes sent:         0       

    actual data pkts:      18695           actual data pkts:          0       

    actual data bytes:  25556632           actual data bytes:         0     

    rexmt  data pkts:       1605           rexmt data pkts:           0       

    rexmt  data bytes:   2188780           rexmt data bytes:          0  

计算方式:

1605/18695* 100 = 8.5% 

 

8.2.3 案例分析——通过时间计算转发

    tcptrace工具提供了可以根据不同标尺(协议,端口,时间等)显示数据的模块,其中slice模块可以根据运行时间查看TCP性能。你可以准确地测量出何时发生了大量的包转发并与其他性能数据相结合来判断性能瓶颈之所在。

下面的示例展示了如何使用slice模块:

# tcptrace xslice bigfile 

命令会在当前目录生成一个叫slice.dat的文件,这个文件包含了15秒为间隔的转发信息:

# ls -l slice.dat  

-rw-r--r-- 1 root root 3430 Jul 10 22:50 slice.dat 

# more slice.dat  

date                segs    bytes  rexsegs rexbytes      new   active 

--------------- -------- -------- -------- -------- -------- -------- 

22:19:41.913288       46     5672        0        0        1        1 

22:19:56.913288      131    25688        0        0        0        1 

22:20:11.913288        0        0        0        0        0        0 

22:20:26.913288     5975  4871128        0        0        0        1 

22:20:41.913288    31049 25307256        0        0        0        1 

22:20:56.913288    23077 19123956       40    59452        0        1 

22:21:11.913288    26357 21624373        5     7500        0        1 

22:21:26.913288    20975 17248491        3     4500       12       13 

22:21:41.913288    24234 19849503       10    15000        3        5 

22:21:56.913288    27090 22269230       36    53999        0        2 

22:22:11.913288    22295 18315923        9    12856        0        2 

22:22:26.913288     8858  7304603        3     4500        0        1 

 

8.4 小结

网络性能监测有如下几点:

检查并确保所有网卡运行在适当的速率下。

检查每个网卡的总吞吐量并确保其符合网速。

监测网络流量类型以确保适当的流量有适当的优先级。

附:渐进式性能监测案例

    下面的案例中一个终端用户报告了一个web用户接口需要20分钟才能处理完本该15分钟就能搞定的问题。

系统配置:

* RHEL3.7

* Dell 1850双核处理器,2G内存,75G 15K硬盘

标准LAMP架构

性能分析流程:

1.vmstat判断基本信息

# vmstat 1 10 

procs                      memory      swap          io     system         cpu 

 r  b   swpd   free   buff   cache     si   so    bi    bo   in    cs  us  sy id wa 

 1  0 249844  19144  18532 1221212    0    0     7     3   22   17  25  8 17  18 

 0  1 249844  17828  18528 1222696    0    0 40448     8  1384  1138 13  7 65  14 

 0  1 249844  18004  18528 1222756    0    0 13568     4   623   534  3  4 56  37 

 2  0 249844  17840  18528 1223200    0    0 35200     0  1285  1017 17  7 56  20 

 1  0 249844  22488  18528 1218608    0    0 38656     0  1294  1034 17  7 58  18 

 0  1 249844  21228  18544 1219908    0    0 13696   484  609   559  5  3 54  38 

 0  1 249844  17752  18544 1223376    0    0 36224     4  1469  1035 10  6 67  17 

 1  1 249844  17856  18544 1208520    0    0 28724     0  950   941  33 12 49  7 

 1  0 249844  17748  18544 1222468    0    0 40968     8  1266  1164 17  9 59  16 

 1  0 249844  17912  18544 1222572    0    0 41344    12  1237  1080 13  8 65  13 

关键点:

* siso0swpdfree稳定,说明内存够用;

* idle保持在50%左右,说明CPU也没问题;

* csbo值都很高;

* wa保持在20%左右。

 

2.使用iostat判断数据读取请求来自哪里

 

关键点:

唯一活动的分区时/dev/sda3

* sda3上有1200左右的IOPSr/s);

* rkB/s0,这点与vmstat观察到的高IO等待相符;

IOPSvmstat观察到的高cs值相符。

 

3.使用top命令判定活跃度最高的应用

# top -d 1 

 11:46:11  up 3 days, 19:13,  1 user,  load average: 1.72, 1.87, 1.80 

176 processes: 174 sleeping, 2 running, 0 zombie, 0 stopped 

CPU states:  cpu    user    nice  system    irq  softirq  iowait    idle 

           total   12.8%    0.0%    4.6%   0.2%     0.2%   18.7%   63.2% 

           cpu00   23.3%    0.0%    7.7%   0.0%     0.0%   36.8%   32.0% 

           cpu01   28.4%    0.0%   10.7%   0.0%     0.0%   38.2%   22.5% 

           cpu02    0.0%    0.0%    0.0%   0.9%     0.9%    0.0%   98.0% 

           cpu03    0.0%    0.0%    0.0%   0.0%     0.0%    0.0%  100.0% 

Mem:  2055244k av, 2032692k used,   22552k free,  0k shrd,   18256k buff 

                   1216212k actv,  513216k in_d,   25520k in_c 

Swap: 4192956k av,  249844k used, 3943112k free                 1218304k cached  

 

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                          

14939 mysql     25   0  379M 224M 1117 R  38.2 25.7% 15:17.78 mysqld    

 4023 root      15   0  2120  972  784 R  2.0  0.3   0:00.06 top     

    1 root      15   0  2008  688  592 S  0.0  0.2   0:01.30 init                

    2 root      34  19     0    0    0 S  0.0  0.0   0:22.59 ksoftirqd/0         

    3 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 watchdog/0          

4 root      10  -5     0    0    0 S  0.0  0.0   0:00.05 events/0    

 

关键点:

* mysql进程使用系统资源最多;

* mysql的大量请求导致IO等待。

4.使用strace命令观察读取请求的来路

# strace -p 14939 

 

Process 14939 attached - interrupt to quit 

read(29, "\3\1\237\1\366\337\1\222%\4\2\0\0\0\0\0012P/d", 20) = 20 

read(29, "ata1/strongmail/log/strongmail-d"..., 399) = 399 

_llseek(29, 2877621036, [2877621036], SEEK_SET) = 0 

read(29, "\1\1\241\366\337\1\223%\4\2\0\0\0\0\0012P/da", 20) = 20 

read(29, "ta1/strongmail/log/strongmail-de"..., 400) = 400 

_llseek(29, 2877621456, [2877621456], SEEK_SET) = 0 

read(29, "\1\1\235\366\337\1\224%\4\2\0\0\0\0\0012P/da", 20) = 20 

read(29, "ta1/strongmail/log/strongmail-de"..., 396) = 396 

_llseek(29, 2877621872, [2877621872], SEEK_SET) = 0 

read(29, "\1\1\245\366\337\1\225%\4\2\0\0\0\0\0012P/da", 20) = 20 

read(29, "ta1/strongmail/log/strongmail-de"..., 404) = 404 

_llseek(29, 2877622296, [2877622296], SEEK_SET) = 0 

read(29, "\3\1\236\2\366\337\1\226%\4\2\0\0\0\0\0012P/d", 20) = 20

关键点:

数据表明mysql在执行大量的随机IO

大量的读取请求来自一个特别的查询。

 

5.使用mysqladmin命令检查查询耗时最长的语句

# ./mysqladmin -pstrongmail processlist 

 

+----+------+-----------+------------+---------+------+----------+---------------------------------------- 

| Id | User | Host      | db         | Command | Time | State    | Info                                                 

+----+------+-----------+------------+---------+------+----------+---------------------------------------- 

| 1  | root | localhost | strongmail | Sleep   | 10   |          |                                                      

| 2  | root | localhost | strongmail | Sleep   | 8    |          |                                                      

| 3  | root | localhost | root       | Query   | 94   | Updating | update `failures` set 

ùpdate_datasource`='Y' where database_id='32' and  update_datasource='N' and  | 

| 14 | root | localhost |            | Query   | 0    |          | show processlist       

 

关键点:

* mysql不断地执行update查询至failures表;

为了实施update,数据库必须对该表进行索引。

就是mysql的这个动作导致了系统性能的下降。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值