linuxr下sar调优工具的深入分析

一)关于CPU资源的监控
sar 1(将所有CPU合并到一起进行监控)
sar -P  ALL 1 100(可以显示每个CPU现在的负载)

如下:
sar -p 1 
Linux 2.6.32-16-generic (ubuntu) 03/23/2011 _x86_64_ (1 CPU)

10:34:49 AM     CPU     %user     %nice   %system   %iowait    %steal     %idle
10:34:50 AM     all      0.00      0.00      0.00      0.00      0.00    100.00
10:34:51 AM     all      0.67      0.00      1.33      0.00      0.33     97.67
10:34:52 AM     all      0.00      0.00      0.66      5.96      0.00     93.38
10:34:53 AM     all      2.00      0.00      1.33      0.00      0.33     96.33
10:34:54 AM     all      0.00      0.00      0.00      0.00      0.00    100.00
10:34:55 AM     all      0.67      0.00      0.67      0.00      0.00     98.67
10:34:56 AM     all      0.33      0.00      0.00      0.00      0.00     99.67
10:34:57 AM     all      0.00      0.00      0.00      0.00      0.00    100.00
10:34:58 AM     all      0.00      0.00      0.33      0.00      0.33     99.34
10:34:59 AM     all      0.00      0.00      0.00      0.00      0.00    100.00
10:35:00 AM     all      3.67      0.00      9.67      0.00      0.00     86.67
10:35:01 AM     all     11.67      0.00     28.67      0.00      0.33     59.33
10:35:02 AM     all     11.96      0.00     28.24      0.00      0.66     59.14
10:35:03 AM     all     16.67      0.00     30.00      0.00      4.67     48.67
10:35:04 AM     all     23.84      0.00     34.44     11.26     11.92     18.54
10:35:05 AM     all     16.56      0.00     34.11      1.99      2.98     44.37
10:35:06 AM     all      8.33      0.00     18.67      0.67      0.67     71.67
10:35:07 AM     all      0.00      0.00      0.33      0.00      0.00     99.67

sar -P ALL 1 100
Linux 2.6.18-6-amd64 (192.168.6.184) 03/23/2011 _x86_64_

12:52:20 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
12:52:21 PM     all      0.00      0.00      0.25      0.00      0.00     99.75
12:52:21 PM       0      0.00      0.00      0.99      0.00      0.00     99.01
12:52:21 PM       1      0.00      0.00      0.00      0.00      0.00    100.00
12:52:21 PM       2      0.00      0.00      0.00      0.00      0.00    100.00
12:52:21 PM       3      0.00      0.00      0.00      0.00      0.00    100.00

12:52:21 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
12:52:22 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
12:52:22 PM       0      0.00      0.00      0.00      0.00      0.00    100.00
12:52:22 PM       1      0.00      0.00      0.00      0.00      0.00    100.00
12:52:22 PM       2      0.00      0.00      0.00      0.00      0.00    100.00
12:52:22 PM       3      0.00      0.00      0.00      0.00      0.00    100.00

注:
%user,%system,%iowait,%idle分别表示用户态进程占用CPU百分比,系统态进程占用CPU百分比,CPU等待IO百分比,CPU空闲百分比
重点说%nice和%steal,这是vmstat所没有了.
%nice:如果一个程序在运行时用nice调整它的优先级,且优先级在1-19之间,并且是用户态的进程,这时%nice才会体现出来,如下:
例如用下面的程序:
# include <stdio.h>
# include <math.h>

int main (void)

{
double pi=M_PI;
double pisqrt;
long i;

for (i=0;i<10000000000;++i){
pisqrt=sqrt(pi);
}
return 0;
}
gcc sqrt.c -o sqrt -lm
nice 10 ./sqrt

在另一个终端观察,此时我们看到%user没有变化,而%nice的CPU利用率达到了100%左右,如下:
12:52:20 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
01:14:54 PM     all      1.00      4.00      0.00      0.00      0.00     95.00
01:14:55 PM     all      0.00    100.00      0.00      0.00      0.00      0.00
01:14:56 PM     all      0.00     99.00      1.00      0.00      0.00      0.00
01:14:57 PM     all      0.00     97.03      2.97      0.00      0.00      0.00
01:14:58 PM     all      0.00    100.00      0.00      0.00      0.00      0.00
01:14:59 PM     all      0.00    100.00      0.00      0.00      0.00      0.00
01:15:00 PM     all      0.00     98.99      1.01      0.00      0.00      0.00
01:15:01 PM     all      1.96     93.14      4.90      0.00      0.00      0.00
01:15:02 PM     all      0.00     82.00      0.00      0.00      0.00     18.00
01:15:03 PM     all      0.00      0.00      0.99      0.00      0.00     99.01
01:15:04 PM     all      0.00      0.00      1.00      0.00      0.00     99.00

%steal:一般在运行虚拟机的宿主机还用到,比如xen,QEMU,Bochs等等.
如下:
12:52:20 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
01:42:03 PM     all      4.67      0.00     10.00      0.00      0.67     84.67
01:42:04 PM     all      5.32      0.00     14.95      0.00      6.64     73.09
01:42:05 PM     all      9.93      0.00     25.17      0.66     11.26     52.98
01:42:06 PM     all      1.00      0.00      2.34      0.00      0.33     96.32
01:42:07 PM     all      0.66      0.00      1.32      0.00      0.33     97.68
01:42:08 PM     all      0.00      0.00      0.67      0.00      0.00     99.33
01:42:09 PM     all      0.33      0.00      0.00      1.33      0.00     98.34


二)关于内存资源的监控

sar -r 1 
Linux 2.6.32-16-generic (ubuntu) 03/23/2011 _x86_64_ (1 CPU)

01:46:21 PM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit
01:46:22 PM     76084    429612     84.95      7160     32024    554500     38.96
01:46:23 PM     76068    429628     84.96      7160     32024    554500     38.96
01:46:24 PM     76068    429628     84.96      7160     32024    554500     38.96
01:46:25 PM     76068    429628     84.96      7160     32024    554500     38.96
01:46:26 PM     76068    429628     84.96      7160     32024    554500     38.96
01:46:27 PM     76068    429628     84.96      7160     32024    554500     38.96
01:46:28 PM     76068    429628     84.96      7160     32024    554500     38.96

注:
kbmemfree:这个值和free命令中的free值基本一致,所以它不包括buffer和cache的空间.
kbmemused:这个值和free命令中的used值基本一致,所以它包括buffer和cache的空间.
%memused:这个值是kbmemused和内存总量(不包括swap)的一个百分比.
kbbuffers和kbcached:这两个值就是free命令中的buffer和cache.
kbcommit:保证当前系统所需要的内存,即为了确保不溢出而需要的内存(RAM+swap).
%commit:这个值是kbcommit与内存总量(包括swap)的一个百分比.

下面我们重点来研究一下kbcommit.

首先编译运行下面的程序:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int
main (int argc, char *argv[])
{
        if (argc != 2)
                exit (0);

        size_t mb = strtoul(argv[1],NULL,0);

        size_t nbytes = mb * 0x100000;
        char *ptr = (char *) malloc(nbytes);
        if (ptr == NULL){
                perror("malloc");
                exit (EXIT_FAILURE);
        }

        size_t i;
        const size_t stride = sysconf(_SC_PAGE_SIZE);
        for (i = 0;i < nbytes; i+= stride) {
                ptr[i] = 0;
        }

        printf("allocated %d mb\n", mb);
        pause();
        return 0;
}

gcc hog.c -o hog
./hog 100
allocated 100 mb

同样在另一个终端查看当前内存的变化,如下:
sar -r 1 
Linux 2.6.32-16-generic (ubuntu) 03/23/2011 _x86_64_ (1 CPU)

10:48:28 AM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit
10:48:29 AM    109928    395768     78.26     64592    198608    247156     17.37
10:48:30 AM    109928    395768     78.26     64592    198608    247156     17.37
10:48:31 AM    109920    395776     78.26     64592    198608    247156     17.37
10:48:32 AM     88212    417484     82.56     64592    198608    349664     24.57
10:48:33 AM      7192    498504     98.58     64592    198608    349664     24.57
10:48:34 AM      7192    498504     98.58     64592    198608    349664     24.57
10:48:35 AM    109404    396292     78.37     64592    198608    247172     17.37
10:48:36 AM    109424    396272     78.36     64592    198608    247172     17.37
10:48:37 AM    109424    396272     78.36     64592    198608    247172     17.37
10:48:38 AM    109424    396272     78.36     64592    198608    247172     17.37

注:我们看到kbcommit由247156kb变成了349664kb,在程序中停止后,kbcommit又恢复到了247156kb.
说明在分配了100MB的内存后,系统对当前需要的内存也随之提高.


三)关于内存分页的监控

sar -B 1
03:12:27 PM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
03:12:28 PM      0.00      0.00     63.64      0.00     64.65      0.00      0.00      0.00      0.00
03:12:29 PM      0.00      0.00     35.64      0.00     62.38      0.00      0.00      0.00      0.00
03:12:30 PM      0.00      0.00     30.00      0.00     62.00      0.00      0.00      0.00      0.00
03:12:31 PM      0.00      0.00     30.00      0.00     65.00      0.00      0.00      0.00      0.00
03:12:32 PM      0.00      0.00     30.00      0.00     62.00      0.00      0.00      0.00      0.00
03:12:33 PM      0.00      0.00     30.00      0.00     64.00      0.00      0.00      0.00      0.00

注:
pgpgin/s:表示每秒从磁盘或SWAP置换到内存的字节数(KB)
pgpgout/s:表示每秒从内存置换到磁盘或SWAP的字节数(KB)
fault/s:每秒钟系统产生的缺页数,即主缺页与次缺页之和(major + minor)
majflt/s:每秒钟产生的主缺页数.
pgfree/s:每秒被放入空闲队列中的页个数
pgscank/s:每秒被kswapd扫描的页个数
pgscand/s:每秒直接被扫描的页个数
pgsteal/s:每秒钟从cache中被清除来满足内存需要的页个数
%vmeff:每秒清除的页(pgsteal)占总扫描页(pgscank+pgscand)的百分比

我们查看一下当前内存:
 free
             total       used       free     shared    buffers     cached
Mem:        505696     117228     388468          0        488      11232
-/+ buffers/cache:     105508     400188
Swap:       917496          0     917496


运行hog程序:
./hog 100

这里故意以小于空闲内存进行分配,这里我们分配了100MB.

同时运行sar -B 1,如下:
sar -B 1 
Linux 2.6.32-16-generic (ubuntu) 03/23/2011 _x86_64_ (1 CPU)

03:29:52 PM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
03:29:53 PM      0.00      0.00     32.67      0.00     62.38      0.00      0.00      0.00      0.00
03:29:54 PM      8.00      0.00  11044.00      1.00    114.00      0.00      0.00      0.00      0.00
03:29:55 PM      0.00      0.00  14835.00      0.00     63.00      0.00      0.00      0.00      0.00
03:29:56 PM      0.00      0.00     30.00      0.00     64.00      0.00      0.00      0.00      0.00
03:29:57 PM      0.00      0.00     30.00      0.00     63.00      0.00      0.00      0.00      0.00
03:29:58 PM      0.00      0.00     29.70      0.00     63.37      0.00      0.00      0.00      0.00
03:29:59 PM      0.00      0.00     64.00      0.00  25749.00      0.00      0.00      0.00      0.00

注:这里我们看到fault/s由32.67/s涨到14835.00/s,说明产生了大量的缺页,而主缺页(majflt/s)为0,说明没有从磁盘(swap)读数据到内存,
pgpgin/s和pgpgout/s都是0,说明没有产生到swap空间的输入/输出,说明我们在这里并没有用到swap分区.
最后pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff的输出都是0,说明物理内存够用,而系统没有必要对cache进行清理,以释放空间和对swap扫描以置换空间.


我们下面再看一个例子,根据上面的情况我们知道还剩下400M左右的物理内存,我们这里一次性占用掉400M内存,然后再申请50MB的内存,如下:
./hog 400&
[1] 5234
allocated 400 mb

./hog 50&
allocated 50 mb

同时运行sar -B 1(我们忽略掉每一次申请400MB内存时的监控输出),如下:
sar -B 1
03:42:40 PM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
03:43:09 PM      0.00     27.72   2615.84      0.00   2273.27    475.25   1964.36   2161.39     88.60
03:43:10 PM      0.00    232.00   4836.00      0.00   4999.00   1312.00   4864.00   4875.00     78.93
03:43:11 PM      0.00  12316.83   3586.14      0.00   6685.15   3516.83   3485.15   3555.45     50.78
03:43:12 PM      0.00   7352.00   2040.00      0.00   4303.00   2336.00   1728.00   2222.00     54.68
03:43:13 PM    128.00      0.00     54.00      4.00     62.00      0.00      0.00      0.00      0.00
03:43:14 PM      0.00      0.00     29.70      0.00     64.36      0.00      0.00      0.00      0.00
03:43:15 PM      0.00      0.00     30.00      0.00     63.00      0.00      0.00      0.00      0.00
03:43:16 PM    456.00      0.00     37.00      6.00     65.00      0.00      0.00      0.00      0.00
03:43:17 PM    432.00      0.00     94.00      7.00  12926.00      0.00      0.00      0.00      0.00

注:我们以第三条输出为例,在这个例子中pgpgout/s迅速涨到12316/s,说明产生了大量的swap写入操作.
而为了分配更多的物理内存给当前的请求,pgsteal/s也涨到了3555/s,说明系统的空闲内存已经无法满足程序hog对50MB内存的请求,
所以这里开始回收cache所占用的内存空间给当前程序,而同时系统为了给hog提供内存空间,它对swap和物理内存进行扫描,以获得更多的内存,
所以这里pgscank/s涨到3516/s,pgscand/s涨到3485/s,回收cache和系统需求的比率为50%,说明物理内存已经不能满足需要,这里就要动用swap,来分配内存了.
pgfree/s代表已经释放到空闲队列的内存总量.

如果我们在这里申请200MB呢,如下:
./hog 200&

同时运行sar -B 1,如下:
sar -B 1
Linux 2.6.32-16-generic (ubuntu) 03/23/2011 _x86_64_ (1 CPU)

10:54:34 AM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
10:54:35 AM      0.00    444.00   5948.00      0.00   6179.00   1152.00   4224.00   5153.00     95.85
10:54:36 AM      0.00    552.00   7020.00      0.00   7164.00    992.00   4576.00   5411.00     97.18
10:54:37 AM      0.00  12640.82   6293.88      0.00   9745.92   4146.94   5518.37   5390.82     55.77
10:54:38 AM      0.00  18019.80   5787.13      0.00  10540.59   4499.01   5924.75   5198.02     49.87
10:54:39 AM     54.90  17003.92   1207.63      0.44   2696.95   1394.99  43894.77   1295.86      2.86

注:这里出现了非常极端的情况,在第5条输出的时候,pgfree/s已经明显小于pgscank/s和pgscand/s,而%vmeff的比例也从49.87%到了2.86%,
说明系统无法迅速释放内存来满足要求,从而进入无尽的SWAP置换.


四)关于I节点,文件和其它内核表的监控

sar -v 1 
Linux 2.6.32-16-generic (ubuntu)        03/24/2011      _x86_64_        (1 CPU)

01:16:52 AM dentunusd   file-nr  inode-nr    pty-nr
01:16:53 AM      4357      2464      5975        10
01:16:54 AM      4357      2464      5975        10
01:16:55 AM      4357      2464      5975        10
01:16:56 AM      4357      2464      5975        10
01:16:57 AM      4357      2464      5975        10

dentunusd:在缓冲目录条目中没有使用的条目数量.
file-nr:被系统使用的文件句柄数量.
inode-nr:使用的索引节点数量.
pty-nr:使用的pty数量.

1)dentunusd
dentunusd数据的数据来源是/proc/sys/fs/dentry-state的第二项数据.
要弄明白它的意义,我们首先要弄明白dcache(目录高速缓存),因为系统中所有的inode都是通过文件名来访问的,而为了解决文件名到inode转换的时间,就引入了dcache.
它是VFS层为当前活动和最近使用的名字维护的一个cache.
dcache中所有处于unused状态和negative(消极)状态的dentry对象都通链入到dentry_unused链表中,这种dentry对象在回收内存时可能会被释放.

如果我们在系统中运行ls -ltR /etc/会看到dentunusd的数量会多起来.
而通过mount -o remount /dev/sda1会看到dentunusd会迅速会回收.


2)file-nr
file-nr的的数据来源是/proc/sys/fs/file-nr文件的第一项数据.
实际上file-nr不是一个准确的值,file-nr每次增加的步长是64(64位系统),例如现在file-nr为2528,实际上可能只打开了2527个文件,而此时你打开两个文件后,它就会变成2592,而不是2530.

3)inode-nr
inode-nr的数据来源是/proc/sys/fs/inode-nr文件的第一项数据减去第二项数据的值.
inode-nr文件的第一项数据是已经分配过的INODE节点.第二项数据是空闲的INODE节点.
例如,inode-nr文件里的值为:13720   7987
我们新建一个文件file1,此时inode-nr第一项数据会加1,就是13721,表示系统里建立了这么多的inode.
我们再删除掉file1,此时就会变成13720.
空闲的INODE节点表示我们已经里这么多的INODE节点曾经有过被利用,但没有被释放.
所以INODE节点总数减去空闲的INODE,就是正在被用的INODE.
最后通过使用mount -o remount /dev/sda1命令,空闲节点会被刷新,所以inode-nr的值会有所变化.

4)pty-nr
pty-nr的数据来源是/proc/sys/kernel/pty/nr
表示登陆过的终端总数,如果我们登录过10回,退出了3回,最后的结果还是10回.



五)关于中断的监控


sar -I ALL  1
Linux 2.6.32-16-generic (ubuntu)        03/24/2011      _x86_64_        (1 CPU)

01:14:27 AM      INTR    intr/s
01:14:28 AM         0     82.18
01:14:28 AM         1      0.00
01:14:28 AM         2      0.00
01:14:28 AM         3      0.00
01:14:28 AM         4      0.00
01:14:28 AM         5      0.00
01:14:28 AM         6      0.00
01:14:28 AM         7      0.00
01:14:28 AM         8      0.00
01:14:28 AM         9      0.00
01:14:28 AM        10      2.97
01:14:28 AM        11      0.00
01:14:28 AM        12      0.00
01:14:28 AM        13      0.00
01:14:28 AM        14      0.00
01:14:28 AM        15     22.77

01:14:28 AM      INTR    intr/s
01:14:29 AM         0     81.00
01:14:29 AM         1      0.00
01:14:29 AM         2      0.00
01:14:29 AM         3      0.00
01:14:29 AM         4      0.00
01:14:29 AM         5      0.00
01:14:29 AM         6      0.00
01:14:29 AM         7      0.00
01:14:29 AM         8      0.00
01:14:29 AM         9      0.00
01:14:29 AM        10      4.00
01:14:29 AM        11      0.00
01:14:29 AM        12      0.00
01:14:29 AM        13      0.00
01:14:29 AM        14      0.00
01:14:29 AM        15      0.00

注:INTR表示中断号,中断号代表的意义可以到/proc/interrupts查询.
intr/s表示每秒的中断次数.


六)关于平均负载和队列的监控

sar -q 1
Linux 2.6.32-16-generic (ubuntu)        03/24/2011      _x86_64_        (1 CPU)

01:25:39 AM   runq-sz  plist-sz   ldavg-1   ldavg-5  ldavg-15
01:25:40 AM         0       203      0.00      0.00      0.00
01:25:41 AM         0       203      0.00      0.00      0.00
01:25:42 AM         0       203      0.00      0.00      0.00
01:25:43 AM         0       203      0.00      0.00      0.00

注:
runq-sz:处于运行或就绪的进程数量
plist-sz:现在进程的总数(包括线程).
ldavg-1:最近一分钟的负载.
ldavg-5:最近五分钟的负载.
ldavg-15:最近十分钟的负载.
平均负载和队列的数据来源于/proc/loadavg


七)关于网络设备的监控

sar -n DEV 1 1000
Linux 2.6.32-16-generic (ubuntu) 03/24/2011 _x86_64_ (1 CPU)

12:25:55 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
12:25:56 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
12:25:56 PM      eth0      5.05      1.01      0.73      0.18      0.00      0.00      0.00

12:25:56 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
12:25:57 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
12:25:57 PM      eth0      1.00      1.00      0.06      0.38      0.00      0.00      0.00


rxpck/s:每秒钟收到数据包的数量.
txpck/s:每秒钟发送数据包的数量.
rxkB/s:每秒钟接收的字节(KB).
txkB/s:每秒钟发送的字节(KB).
rxcmp/s:每秒收到的压缩包的数量
txcmp/s:每秒发出的压缩包的数量
rxmcst/s:每秒收到的广播包的数量
网络设备的数据来源于/proc/net/dev.
我这里尝试用ssh的压缩功能进行传输,结果也没看到压缩包的数量有变化.
尝试发送或接收广播包/组播包时rxmcst/s也不会有变化.


八)关于NFS的监控

1)关于NFS客户端的监控

在NFS客户端用下面的命令监控:
sar -n NFS 1
02:57:45 AM    call/s retrans/s    read/s   write/s  access/s  getatt/s
02:57:46 AM      0.00      0.00      0.00      0.00      0.00      0.00
02:57:47 AM      0.00      0.00      0.00      0.00      0.00      0.00
02:57:48 AM      0.00      0.00      0.00      0.00      0.00      0.00
02:57:49 AM      0.00      0.00      0.00      0.00      0.00      0.00

call/s:每秒成功的RPC调用都会使call/s的值增长,比如对NFS的一次读/写.
retrans/s:每秒重传的RPC次数,比如因为服务器的问题,产生timeout,这时客户端需要重新传输.
read/s:每秒从NFS服务端读取的次数.
write/s:每秒写入到NFS服务端的次数.
access/s:每秒访问NFS的次数,比如从NFS服务端COPY文件.
getatt/s:每秒获取NFS服务端文件属性的次数,比如ls -l /NFSSERVER/,如果NFSSERVER有300个文件,将产生300次这样的请求.

我们对以上几次监控数据进行演示:

用dd命令写300M的数据到NFS服务端:
dd if=/dev/zero  of=/mnt/test bs=1M count=300
300+0 records in
300+0 records out
314572800 bytes (315 MB) copied, 29.3891 s, 10.7 MB/s

在另一个终端查看NFS的监控输出:

sar -n NFS 1
03:10:06 AM    call/s retrans/s    read/s   write/s  access/s  getatt/s
03:10:21 AM    196.00      0.00      0.00    192.00      1.00      1.00
03:10:22 AM    773.00      0.00      0.00    768.00      0.00      0.00
03:10:23 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:10:24 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:10:25 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:10:26 AM    705.00      0.00      0.00    704.00      0.00      0.00
03:10:27 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:10:28 AM    195.00      0.00      0.00    192.00      0.00      0.00
03:10:29 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:10:30 AM    516.00      0.00      0.00    512.00      0.00      0.00
03:10:31 AM    129.00      0.00      0.00    128.00      0.00      0.00
03:10:32 AM     65.00      0.00      0.00     64.00      0.00      0.00
03:10:33 AM    259.00      0.00      0.00    256.00      0.00      0.00
03:10:34 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:10:35 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:10:36 AM   1142.00      0.00      0.00   1140.00      0.00      0.00
03:10:37 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:10:38 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:10:39 AM    873.00      0.00      0.00    845.00      0.00      0.00


我们看到call/s基本上是其它数据之和,因为我们是向NFS服务端写数据,所以write/s会有变化,而access/s只是第一次打开文件时用到,getatt/s同样是这样.


用dd命令从NFS服务端读300M的数据到本地:
dd if=/mnt/test of=/tmp/test  bs=1M count=300

在另一个终端查看NFS的监控输出:
sar -n NFS 1
03:33:43 AM    212.00      0.00    210.00      0.00      1.00      1.00
03:33:44 AM    300.00      0.00    300.00      0.00      0.00      0.00
03:33:45 AM    285.00      0.00    285.00      0.00      0.00      0.00
03:33:46 AM    285.00      0.00    285.00      0.00      0.00      0.00
03:33:47 AM    281.00      0.00    281.00      0.00      0.00      0.00
03:33:48 AM    270.00      0.00    270.00      0.00      0.00      0.00
03:33:49 AM    285.00      0.00    285.00      0.00      0.00      0.00
03:33:50 AM    315.00      0.00    315.00      0.00      0.00      0.00
03:33:51 AM    249.00      0.00    249.00      0.00      0.00      0.00
03:33:52 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:33:53 AM      0.00      0.00      0.00      0.00      0.00      0.00

注:我们看到写NFS的实验中,数据是不连续的,而读NFS的实验中数据是连接的,原因是写的时候我们直接从/dev/zero读取再写入,而由于网络的瓶颈,所以是不连续的,
而读NFS的实验我们是从物理文件中读取,由于它不像/dev/zero读取那样快,所以输出是连续的.


下面我们看一下access/s和getatt/s

mount -t 10.1.6.81:/etc /mnt/
ls -ltR /mnt/

在另一个终端查看NFS的监控输出:

sar -n NFS 1
03:10:06 AM    call/s retrans/s    read/s   write/s  access/s  getatt/s
03:26:55 AM     13.00      0.00      0.00      0.00      1.00      1.00
03:26:56 AM    221.00      0.00      0.00      0.00      9.00      9.00
03:26:57 AM     14.00      0.00      0.00      0.00      2.00      2.00
03:26:58 AM      4.00      0.00      0.00      0.00      1.00      1.00
03:26:59 AM    214.00      0.00      0.00      0.00     20.00     20.00
03:27:00 AM    180.00      0.00      0.00      0.00     34.00     34.00
03:27:01 AM    159.00      0.00      0.00      0.00     49.00     48.00
03:27:02 AM    176.00      0.00      0.00      0.00     48.00     56.00
03:27:03 AM    128.00      0.00      0.00      0.00     41.00     41.00
03:27:04 AM    469.00      0.00      0.00      0.00     48.00     48.00
03:27:05 AM      9.00      0.00      0.00      0.00      3.00      3.00
03:27:06 AM     78.00      0.00      0.00      0.00     26.00     26.00

注意我们第一次读取的时,access/s和getatt/s基本一致,而它们的和与call/s大相径庭,我们再做一次ls -ltR /mnt的操作,再次查看NFS监控输出:
03:44:51 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:44:52 AM    129.00      0.00      0.00      0.00      0.00    129.00
03:44:53 AM    442.00      0.00      0.00      0.00      0.00    442.00
03:44:54 AM    278.00      0.00      0.00      0.00      0.00    278.00
03:44:55 AM    473.00      0.00      0.00      0.00      0.00    473.00
03:44:56 AM    295.00      0.00      0.00      0.00      0.00    295.00
03:44:57 AM    827.00      0.00      0.00      0.00      0.00    827.00
03:44:58 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:44:59 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:45:00 AM     47.00      0.00      0.00      0.00      0.00     47.00
03:45:01 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:45:02 AM      0.00      0.00      0.00      0.00      0.00      0.00
03:45:03 AM      0.00      0.00      0.00      0.00      0.00      0.00

这里access/s与getatt/s不一致,而它们的和与call/s基本相同了,原因是第一次访问时系统对access/s做了文件系统缓存(cache),所以第二次访问直接读取了内存,而getatt(获取属性)却不能这样做.
我们清理cache,再看一下:
echo 3 > /proc/sys/vm/drop_caches
ls -ltR /mnt/

输出如下:
03:48:22 AM     13.00      0.00      0.00      0.00      1.00      1.00
03:48:23 AM    171.29      0.00      0.00      0.00      8.91      7.92
03:48:24 AM     48.00      0.00      0.00      0.00      0.00      1.00
03:48:25 AM     91.00      0.00      0.00      0.00     23.00     23.00
03:48:26 AM    141.00      0.00      0.00      0.00      0.00      0.00
03:48:27 AM     69.00      0.00      0.00      0.00      3.00      3.00
03:48:28 AM     51.00      0.00      0.00      0.00     14.00     14.00
03:48:29 AM    142.00      0.00      0.00      0.00     43.00     43.00
03:48:30 AM    410.00      0.00      0.00      0.00    121.00    129.00
03:48:31 AM    440.00      0.00      0.00      0.00     39.00     38.00
03:48:32 AM     15.00      0.00      0.00      0.00      5.00      5.00
03:48:33 AM     72.00      0.00      0.00      0.00     24.00     24.00
03:48:34 AM      0.00      0.00      0.00      0.00      0.00      0.00

我们看到又恢复到第一次查询时的状态.
本项输出的数据来源于/proc/net/rpc/nfs


2)关于NFS服务端的监控

这里要在NFS服务端进行监控.

以下是模拟对NFS服务器进行大量写入操作的例子.
sar -n NFSD 1 1000
02:05:41 PM   scall/s badcall/s  packet/s     udp/s     tcp/s     hit/s    miss/s   sread/s  swrite/s saccess/s sgetatt/s
02:05:42 PM    332.65      0.00    332.65    332.65      0.00      1.02    327.55      0.00    327.55      2.04      0.00
02:05:43 PM      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
02:05:44 PM      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

以下是用UDP模试挂载NFS,再次模拟对NFS服务器进行大量写入操作的例子.
05:10:51 PM   scall/s badcall/s  packet/s     udp/s     tcp/s     hit/s    miss/s   sread/s  swrite/s saccess/s sgetatt/s
02:04:30 PM      1.01      0.00      1.01      1.01      0.00      0.00      0.00      0.00      0.00      1.01      0.00
02:04:31 PM      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
02:04:32 PM    333.00      0.00    333.00    333.00      0.00      1.00    323.00      0.00    321.00      1.00      3.00
02:04:33 PM      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

注:以上的两个例子我们分别用TCP(默认)/UDP两种模试进行模拟测试.
用指定TCP的方式挂载NFS:
mount -t nfs -o tcp,remount ip:/tmp /mnt/
用指定UDP的方式挂载NFS
mount -t nfs -o udp,remount ip:/tmp /mnt/
hit/s和miss/s代表每秒缓存命中和缓存未命中的次数,这个在写NFS服务端会有变化.
其余各列数据与NFS客户端一致,在则不进行重复.
本项输出的数据来源于/proc/net/rpc/nfsd



八)关于套接字的监控

sar -n SOCK 1 1000

02:21:28 PM    totsck    tcpsck    udpsck    rawsck   ip-frag
02:21:29 PM       112        11        12         0         0
02:21:30 PM       112        11        12         0         0
02:21:31 PM       112        11        12         0         0
02:21:32 PM       112        11        12         0         0
02:21:33 PM       112        11        12         0         0
02:21:34 PM       112        11        12         0         0
02:21:35 PM       112        11        12         0         0
02:21:36 PM       112        11        12         0         0

注:
totsck:代表现在有多少个SOCKET连接,比如进行一次ssh连接,totsck将加1,同样断开连接相应的也会减少.
tcpsck:代表现在有多少个处在监听状态的TCP套接字.如下:
netstat -tlnp|grep LISTEN
tcp        0      0 127.0.0.1:2208              0.0.0.0:*                   LISTEN      2228/hpiod          
tcp        0      0 0.0.0.0:2049                0.0.0.0:*                   LISTEN      -                   
tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LISTEN      1937/portmap        
tcp        0      0 192.168.27.130:22           0.0.0.0:*                   LISTEN      3001/sshd           
tcp        0      0 0.0.0.0:886                 0.0.0.0:*                   LISTEN      1976/rpc.statd      
tcp        0      0 0.0.0.0:791                 0.0.0.0:*                   LISTEN      2732/rpc.mountd     
tcp        0      0 0.0.0.0:23                  0.0.0.0:*                   LISTEN      2286/xinetd         
tcp        0      0 127.0.0.1:631               0.0.0.0:*                   LISTEN      2250/cupsd          
tcp        0      0 0.0.0.0:763                 0.0.0.0:*                   LISTEN      2703/rpc.rquotad    
tcp        0      0 0.0.0.0:57500               0.0.0.0:*                   LISTEN      -                   
tcp        0      0 127.0.0.1:2207              0.0.0.0:*                   LISTEN      2233/python         
tcp        0      0 ::1:631                     :::*                        LISTEN      2250/cupsd 
在这里最后一个SOCK套接字将不会统计在tcpsck里,因为它的listen调用没有绑定具体的IP地址.
udpsck:代表现在有多少个处在监听状态的UDP套接字.
rawsck:代表原始套接字,原始套接字可以接收本机网卡上的数据帧或者数据包,对与监听网络的流量和分析是很有作用的.
if-frag:代表IP分片次数.


九)关于I/O及速率的监控

sar -b 1 100

07:17:58 AM       tps      rtps      wtps   bread/s   bwrtn/s
07:17:59 AM      7.00      0.00      7.00      0.00    368.00
07:18:00 AM      0.00      0.00      0.00      0.00      0.00
07:18:01 AM      0.00      0.00      0.00      0.00      0.00
07:18:02 AM      0.00      0.00      0.00      0.00      0.00
07:18:03 AM      0.00      0.00      0.00      0.00      0.00
07:18:04 AM      0.00      0.00      0.00      0.00      0.00

注:
tps:每秒从物理磁盘I/O的次数.多个逻辑请求会被合并为一个I/O磁盘请求,一次传输的大小是不确定的.
rtps:每秒的读请求数
wtps:每秒的写请求数
bread/s:每秒读磁盘的数据块数(in blocks  1 block = 512B, 2.4以后内核)
bwrtn/s:每秒写磁盘的数据块数(in blocks  1 block = 512B, 2.4以后内核)

一般情况下tps=(rtps+wtps)
先收回cache.
echo 3 > /proc/sys/vm/drop_caches 
dd if=/tmp/tmp of=/tmp/tmp1 bs=1M

再观察sar的输出:
07:25:22 AM       tps      rtps      wtps   bread/s   bwrtn/s
07:25:23 AM    250.50    162.38     88.12  45100.99  24475.25
07:25:24 AM    305.00    203.00    102.00  90976.00  24640.00
07:25:25 AM    116.00     15.00    101.00   5488.00  24864.00
07:25:26 AM      0.00      0.00      0.00      0.00      0.00
07:25:27 AM      0.00      0.00      0.00      0.00      0.00
07:25:28 AM    117.17      0.00    117.17      0.00  33785.86


十)关于块设备活动状况的监控

先清理cache.
echo 3 > /proc/sys/vm/drop_caches
dd if=/tmp/tmp of=/tmp/tmp1 bs=1M

观察sar的输出:
sar -d 1 10000 -p
07:32:59 AM       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
07:33:00 AM       sda    120.37  23014.81   5837.04    239.69      1.66     13.75      3.22     38.70
07:33:00 AM       hdc      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

07:33:00 AM       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
07:33:01 AM       sda    320.00 106624.00  18720.00    391.70      2.29      7.19      2.45     78.30
07:33:01 AM       hdc      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

07:33:01 AM       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
07:33:02 AM       sda    209.00  26960.00  33152.00    287.62      3.21     15.34      1.53     31.90
07:33:02 AM       hdc      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

注:
用参数-p可以打印出sda,hdc等磁盘设备名称,如果不用参数-p,设备节点则有可能是dev8-0,dev22-0
tps:每秒从物理磁盘I/O的次数.多个逻辑请求会被合并为一个I/O磁盘请求,一次传输的大小是不确定的.
rd_sec/s:每秒读扇区的次数.
wr_sec/s:每秒写扇区的次数.
avgrq-sz:平均每次设备I/O操作的数据大小(扇区).
avgqu-sz:磁盘请求队列的平均长度.
await:从请求磁盘操作到系统完成处理,每次请求的平均消耗时间,包括请求队列等待时间,单位是毫秒(1秒=1000毫秒).
svctm:系统处理每次请求的平均时间,不包括在请求队列中消耗的时间.
%util:I/O请求占CPU的百分比,比率越大,说明越饱和.

该数据的来源是/proc/diskstats.


十一)关于sar的一些结束语

1)sar与它的时间段

sar也可以查看非实时的数据,它是通过cron周期的运行sysstat脚本,将数据产生到指定的目录下,例如:/var/log/sa/sa27
sa27就是本月27日,指定具体的时间可以通过-s(start)和-e(end)来指定.
例如:我们想查看本月27日,从0点到23点的内存资源.

sar -f /var/log/sa/sa27 -s 00:00:00 -e 23:00:00 -r

03:52:14 AM       LINUX RESTART

04:00:01 AM kbmemfree kbmemused  %memused kbbuffers  kbcached kbswpfree kbswpused  %swpused  kbswpcad
04:10:01 AM    237268    278332     53.98     44328    183584   1052248         0      0.00         0
04:20:01 AM    237144    278456     54.01     44476    183592   1052248         0      0.00         0
04:30:01 AM    191988    323612     62.76     45324    227616   1052248         0      0.00         0
04:40:01 AM    191864    323736     62.79     45452    227624   1052248         0      0.00         0
04:50:02 AM    191740    323860     62.81     45576    227628   1052248         0      0.00         0
05:00:01 AM    190252    325348     63.10     45932    227640   1052248         0      0.00         0
Average:       206709    308891     59.91     45181    212947   1052248         0      0.00         0

07:02:35 AM       LINUX RESTART

07:10:01 AM kbmemfree kbmemused  %memused kbbuffers  kbcached kbswpfree kbswpused  %swpused  kbswpcad
07:20:01 AM    277340    238260     46.21     54056    145252   1052248         0      0.00         0
07:30:01 AM    304944    210656     40.86      1684    171196   1052248         0      0.00         0
07:40:01 AM    310168    205432     39.84       752    167940   1052248         0      0.00         0
07:50:01 AM    307568    208032     40.35      1164    169884   1052248         0      0.00         0
08:00:01 AM    302420    213180     41.35      1916    173580   1052248         0      0.00         0
Average:       300488    215112     41.72     11914    165570   1052248         0      0.00         0 

注:上面的输出分成两个时段,这是因为在我们只在这两个时间开了机器,并运行/etc/cron.d/sysstat脚本.
sysstat脚本每十分钟执行一次/usr/lib/sa/sa1脚本,生成监控数据,所以我们看到上面的数据是以十分钟为间隔的.

2)sar的版本

在RHEL5下默认的版本是sysstat 7.0,在7.0版本中,sar的命令有-x/-X对某个进程的监控.
而在新的版本中sysstat 9.x中,sar去掉了-x/-X,并对-n 下的监控项做了调整,增加了ICMP等监控项.并对-v下面的系统资源做了调整.
本篇文章,我们用的是sysstat 9.x.

你可能感兴趣的:(linux,tcp,cache,ubuntu,工具,磁盘)