一. Linux 性能监控的概述
系统由若干子系统构成,通常改动一个子系统有可能影响到另外一个子系统。甚至会导致整个系统不稳定、崩溃。
所以说优化、监測、測试一般是连在一起的,并且是一个循环并且长期的过程,通常监測的子系统有下面这些:
(1). CPU
(2). Memory
(3). IO
(4). Network
这些子系统互相依赖,了解这些子系统的特性,监測这些子系统的性能參数以及及时发现可能会出现的瓶颈对系统优化非常有帮助。
1.1 应用类型
不同的系统用途也不同。要找到性能瓶颈须要知道系统跑的是什么应用、有些什么特点。比方 web server 对系统的要求肯定和 file server 不一样,所以分清不同系统的应用类型非常重要,通常应用能够分为两种类型:
(1)IO 相关。IO 相关的应用通经常使用来处理大量数据,须要大量内存和存储,频繁 IO 操作读写数据,而对 CPU 的要求则较少,大部分时候 CPU 都在等待硬盘。比方,数据库server、文件server等。
(2)CPU 相关。CPU 相关的应用须要使用大量 CPU,比方高并发的 web/mail server、图像/视频处理、科学计算等都可被视作 CPU 相关的应用。
看看实际中的样例。第1个是文件server拷贝一个大文件时表现出来的特征:
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 4 140 1962724 335516 4852308 0 0 388 65024 1442 563 0 2 47 52 0
0 4 140 1961816 335516 4853868 0 0 768 65536 1434 522 0 1 50 48 0
0 4 140 1960788 335516 4855300 0 0 768 48640 1412 573 0 1 50 49 0
0 4 140 1958528 335516 4857280 0 0 1024 65536 1415 521 0 1 41 57 0
0 5 140 1957488 335516 4858884 0 0 768 81412 1504 609 0 2 50 49 0
第2个是 CPU 做大量计算时表现出来的特征:
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
4 0 140 3625096 334256 3266584 0 0 0 16 1054 470 100 0 0 0 0
4 0 140 3625220 334264 3266576 0 0 0 12 1037 448 100 0 0 0 0
4 0 140 3624468 334264 3266580 0 0 0 148 1160 632 100 0 0 0 0
4 0 140 3624468 334264 3266580 0 0 0 0 1078 527 100 0 0 0 0
4 0 140 3624712 334264 3266580 0 0 0 80 1053 501 100 0 0 0 0
上面两个样例最明显的区别就是 id 一栏,代表 CPU 的空暇率,复制文件时候 id 维持在 50% 左右。CPU 大量计算的时候 id 基本为 0。
1.2 底线
事先建立一个底线,假设性能监測得到的统计数据跨过这条线,我们就能够说这个系统性能差,假设数据能保持在线内我们就说性能好。建立这样底线须要知道一些理论、额外的负载測试和系统管理员多年的经验。假设自己没有多年的经验,有一个简单划底线的办法就是:把这个底线建立在自己对系统的期望上。自己期望这个系统有个什么样的性能,这是一个底线,假设没有达到这个要求就是性能差。
1.3 监測工具
工具 | 简介 |
top | 查看进程活动状态以及一些系统状况 |
vmstat | 查看系统状态、硬件和系统信息等 |
iostat | 查看CPU 负载,硬盘状况 |
sar | 综合工具。查看系统状况 |
mpstat | 查看多处理器状况 |
netstat | 查看网络状况 |
iptraf | 实时网络状况监測 |
tcpdump | 抓取网络数据包,具体分析 |
mpstat | 查看多处理器状况 |
tcptrace | 数据包分析工具 |
netperf | 网络带宽工具 |
dstat | 综合工具,综合了 vmstat, iostat, ifstat, netstat 等多个信息 |
二. CPU
CPU 的占用主要取决于什么样的资源正在 CPU 上面执行。比方拷贝一个文件通常占用较少 CPU。由于大部分工作是由 DMA(Direct Memory Access)完毕,仅仅是在完毕拷贝以后给一个中断让 CPU 知道拷贝已经完毕;科学计算通常占用较多的 CPU。大部分计算工作都须要在 CPU 上完毕,内存、硬盘等子系统仅仅做临时的数据存储工作。要想监測和理解 CPU 的性能须要知道一些的操作系统的基本知识,比方:中断、进程调度、进程上下文切换、可执行队列等。
这里用个样例来简介一下这些概念和他们的关系。CPU每时每刻都有工作在做(进程、线程)而且自己有一张工作清单(可执行队列)。由老板(进程调度)来决定他该干什么,他须要和老板沟通以便得到老板的想法并及时调整自己的工作(上下文切换)。部分工作做完以后还须要及时向老板汇报(中断),所以打工仔(CPU)除了做自己该做的工作以外。还有大量时间和精力花在沟通和汇报上。
CPU 也是一种硬件资源。和不论什么其它硬件设备一样也须要驱动和管理程序才干使用。我们能够把内核的进程调度看作是 CPU 的管理程序,用来管理和分配 CPU 资源,合理安排进程抢占 CPU。并决定哪个进程该使用 CPU、哪个进程该等待。操作系统内核里的进程调度主要用来调度两类资源:进程(或线程)和中断,进程调度给不同的资源分配了不同的优先级,优先级最高的是硬件中断,其次是内核(系统)进程。最后是用户进程。每一个 CPU 都维护着一个可执行队列。用来存放那些可执行的线程。线程要么在睡眠状态(blocked 正在等待 IO)要么在可执行状态,假设 CPU 当前负载太高而新的请求不断,就会出现进程调度临时应付只是来的情况,这个时候就不得不把线程临时放到可执行队列里。
能够从下面几个方面监控CPU的信息:
(1)中断;
(2)上下文切换。
(3)可执行队列。
(4)CPU 利用率。
2.1 底线
通常我们期望我们的系统能到达下面目标:
(1)CPU 利用率。假设 CPU 有 100% 利用率。那么应该到达这样一个平衡:65%-70% User Time,30%-35% System Time。0%-5% Idle Time;
(2)上下文切换,上下文切换应该和 CPU 利用率联系起来看,假设能保持上面的 CPU 利用率平衡,大量的上下文切换是能够接受的;
(3)可执行队列。每一个可执行队列不应该有超过1-3个线程(每处理器),比方:双处理器系统的可执行队列里不应该超过6个线程。
2.2 vmstat
vmstat 是个查看系统总体性能的小工具,小巧、即使在非常 heavy 的情况下也执行良好,而且能够用时间间隔採集得到连续的性能数据。
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 1 140 2787980 336304 3531996 0 0 0 128 1166 5033 3 3 70 25 0
0 1 140 2788296 336304 3531996 0 0 0 0 1194 5605 3 3 69 25 0
0 1 140 2788436 336304 3531996 0 0 0 0 1249 8036 5 4 67 25 0
0 1 140 2782688 336304 3531996 0 0 0 0 1333 7792 6 6 64 25 0
3 1 140 2779292 336304 3531992 0 0 0 28 1323 7087 4 5 67 25 0
參数介绍:
(1). r。可执行队列的线程数。这些线程都是可执行状态,仅仅只是 CPU 临时不可用;
(2). b,被 blocked 的进程数。正在等待 IO 请求;
(3). in,被处理过的中断数
(4). cs,系统上正在做上下文切换的数目
(5). us,用户占用 CPU 的百分比
(6). sys,内核和中断占用 CPU 的百分比
(7). wa。全部可执行的线程被 blocked 以后都在等待 IO,这时候 CPU 空暇的百分比
(8). id,CPU 全然空暇的百分比
举两个现实中的样例来实际分析一下:
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
4 0 140 2915476 341288 3951700 0 0 0 0 1057 523 19 81 0 0 0
4 0 140 2915724 341296 3951700 0 0 0 0 1048 546 19 81 0 0 0
4 0 140 2915848 341296 3951700 0 0 0 0 1044 514 18 82 0 0 0
4 0 140 2915848 341296 3951700 0 0 0 24 1044 564 20 80 0 0 0
4 0 140 2915848 341296 3951700 0 0 0 0 1060 546 18 82 0 0 0
从上面的数据能够看出几点:
(1). interrupts(in)很高。context switch(cs)比較低。说明这个 CPU 一直在不停的请求资源;
(2). user time(us)一直保持在 80% 以上,并且上下文切换较低(cs)。说明某个进程可能一直霸占着 CPU;
(3). run queue(r)刚好在4个。
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
14 0 140 2904316 341912 3952308 0 0 0 460 1106 9593 36 64 1 0 0
17 0 140 2903492 341912 3951780 0 0 0 0 1037 9614 35 65 1 0 0
20 0 140 2902016 341912 3952000 0 0 0 0 1046 9739 35 64 1 0 0
17 0 140 2903904 341912 3951888 0 0 0 76 1044 9879 37 63 0 0 0
16 0 140 2904580 341912 3952108 0 0 0 0 1055 9808 34 65 1 0 0
从上面的数据能够看出几点:
(1). context switch(cs)比 interrupts(in)要高得多。说明内核不得不来回切换进程;
(2). 进一步观察发现 system time(sy)非常高而 user time(us)非常低,并且加上高频度的上下文切换(cs),说明正在执行的应用程序调用了大量的系统调用(system call);
(3). run queue(r)在14个线程以上,依照这个測试机器的硬件配置(四核),应该保持在12个以内。
我上午CPU 100%时的信息:
top - 11:49:08 up 50 days, 22:25, 6 users, load average: 59.79, 59.98, 60.50
Tasks: 200 total, 61 running, 139 sleeping, 0 stopped, 0 zombie
Cpu0 : 26.5%us, 73.5%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu1 : 25.0%us, 75.0%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1939780k total, 1744412k used, 195368k free, 95704k buffers
Swap: 4401800k total, 662836k used, 3738964k free, 811124k cached
[root@localhost ~]# vmstat 2 10
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
58 1 662836 195988 95428 810740 0 0 4 106 4 1 23 4 72 1 0
59 1 662836 195988 95448 810732 0 0 0 128 235 221 28 72 0 0 0
59 1 662836 195988 95448 810768 0 0 0 0 216 209 28 72 0 0 0
2.3 mpstat
mpstat 和 vmstat 类似,不同的是 mpstat 能够输出多个处理器的数据。
注意:须要安装sysstat 包后才有这个命令,能够使用yum安装:
#yum install sysstat
sysstat 包括iostat、mpstat、sar、命令。
[root@localhost gmail]# export LANG=en_US
[root@localhost gmail]# mpstat -P ALL
Linux 2.6.18-8.el5xen (localhost.localdomain) 02/21/2011
10:20:16 PM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
10:20:16 PM all 11.49 0.00 2.58 1.04 0.01 0.13 0.01 84.74 314.61
10:20:16 PM 0 15.73 0.00 2.56 0.55 0.02 0.23 0.01 80.89 241.09
10:20:16 PM 1 7.25 0.00 2.60 1.53 0.00 0.02 0.01 88.59 73.52
[root@localhost gmail]# mpstat -P ALL 1
Linux 2.6.18-8.el5xen (localhost.localdomain) 02/21/2011
10:20:18 PM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
10:20:19 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 136.63
10:20:19 PM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 86.14
10:20:19 PM 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 50.50
10:20:19 PM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
10:20:20 PM all 0.00 0.00 0.00 0.47 0.00 0.00 0.00 99.53 105.00
10:20:20 PM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 79.00
10:20:20 PM 1 0.00 0.00 0.00 0.90 0.00 0.00 0.00 99.10 26.00
2.4 ps
查看某个程序、进程占用了多少 CPU 资源:
[root@localhost gmail]# while :; do ps -eo pid,ni,pri,pcpu,psr,comm | grep 'oracle'; sleep 1; done
PID NI PRI %CPU PSR COMMAND
3668 0 24 0.0 0 oracle
3670 0 21 0.0 0 oracle
3672 0 24 0.0 0 oracle
3674 0 23 0.0 0 oracle
3676 0 24 0.0 1 oracle
3678 0 23 0.0 0 oracle
3680 0 21 0.0 1 oracle
3682 0 24 0.0 1 oracle
3684 0 24 0.0 0 oracle
3686 0 21 0.0 0 oracle
三. Memory
这里的讲到的 “内存” 包含物理内存和虚拟内存。虚拟内存(Virtual Memory)把计算机的内存空间扩展到硬盘,物理内存(RAM)和硬盘的一部分空间(SWAP)组合在一起作为虚拟内存为计算机提供了一个连贯的虚拟内存空间,优点是我们拥有的内存 ”变多了“,能够执行很多其它、更大的程序,坏处是把部分硬盘当内存用总体性能受到影响。硬盘读写速度要比内存慢几个数量级。而且 RAM 和 SWAP之间的交换添加了系统的负担。
在操作系统里,虚拟内存被分成页,在 x86 系统上每一个页大小是 4KB。 Linux 内核读写虚拟内存是以 “页” 为单位操作的,把内存转移到硬盘交换空间(SWAP)和从交换空间读取到内存的时候都是按页来读写的。内存和 SWAP 的这样的交换过程称为页面交换(Paging),值得注意的是 paging 和 swapping 是两个全然不同的概念,国内非常多參考书把这两个概念混为一谈,swapping 也翻译成交换,在操作系统里是指把某程序全然交换到硬盘以腾出内存给新程序使用,和 paging 仅仅交换程序的部分(页面)是两个不同的概念。纯粹的 swapping 在现代操作系统中已经非常难看到了,由于把整个程序交换到硬盘的办法既耗时又费力并且不是必需,现代操作系统基本都是 paging 或者 paging/swapping 混合,swapping 最初是在 Unix system V 上实现的。
在这里仅仅介绍和性能监測有关的两个内核进程:kswapd 和 pdflush。
(1)kswapd daemon 用来检查 pages_high 和 pages_low,假设可用内存少于 pages_low,kswapd 就開始扫描并试图释放 32个页面。而且反复扫描释放的过程直到可用内存大于 pages_high 为止。
扫描的时候检查3件事:
1)假设页面没有改动,把页放到可用内存列表里。
2)假设页面被文件系统改动,把页面内容写到磁盘上;
3)假设页面被改动了。但不是被文件系统改动的。把页面写到交换空间。
(2)pdflush daemon 用来同步文件相关的内存页面。把内存页面及时同步到硬盘上。比方打开一个文件。文件被导入到内存里。对文件做了改动后并保存后,内核并不立即保存文件到硬盘,由 pdflush 决定什么时候把对应页面写入硬盘,这由一个内核參数 vm.dirty_background_ratio 来控制,比方以下的參数显示脏页面(dirty pages)达到全部内存页面10%的时候開始写入硬盘。
# /sbin/sysctl -n vm.dirty_background_ratio
10
3.1 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 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
磁盘一般是计算机最慢的子系统,也是最easy出现性能瓶颈的地方,由于磁盘离 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 server上的物理内存和文件缓存区的情况:
$ cat /proc/meminfo
MemTotal: 8182776 kB
MemFree: 3053808 kB
Buffers: 342704 kB
Cached: 3972748 kB
这台server总共同拥有 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 1
avg-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 %util
sdb 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 %util
sdb 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 1
avg-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 %util
sdb 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 %util
sdb 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/meminfo
MemTotal: 8182776 kB
MemFree: 2125476 kB
Buffers: 347952 kB
Cached: 4892024 kB
SwapCached: 112 kB
...
SwapTotal: 4096564 kB
SwapFree: 4096424 kB
...
$ vmstat 1
procs -----------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 eth0
Settings 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 eth0
5.2 netperf
netperf 执行在 client/server 模式下,比 iptraf 能很多其它样化的測试终端的吞吐量。先在服务器端启动 netserver:
# netserver
Starting netserver at port 12865
Starting netserver at hostname 0.0.0.0 port 12865 and family AF_UNSPEC
然后在client測试server。运行一次持续10秒的 TCP 測试:
# netperf -H 172.16.38.36 -l 10
TCP 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_INET
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 10.32 93.68
从以上输出能够看出,网络吞吐量在 94mbps 左右,对于 100mbps 的网络来说这个性能算的上非常不错。以上測试是在server和client位于同一个局域网,而且局域网是有线网的情况,你也能够试试不同结构、不同速率的网络,比方:网络之间中间多几个路由器、client在 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,32768
TCP 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_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 10.00 243.03
16384 87380
5.3 iperf
iperf 和 netperf 执行方式类似,也是 server/client 模式,先在服务器端启动 iperf:
# iperf -s -D
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
Running Iperf Server as a daemon
The Iperf daemon process ID : 5695
然后在client对server进行測试,client先连接到server端(172.16.38.36),并在30秒内每隔5秒对server和client之间的网络进行一次带宽測试和採样:
# iperf -c 172.16.38.36 -t 30 -i 5
------------------------------------------------------------
Client connecting to 172.16.38.36, TCP port 5001
TCP 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.dmp
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
511942 packets captured
511942 packets received by filter
0 packets dropped by kernel
# tcptrace network.dmp
1 arg remaining, starting with 'network.dmp'
Ostermann's tcptrace -- version 6.6.7 -- Thu Nov 4, 2004
511677 packets seen, 511487 TCP packets traced
elapsed wallclock time: 0:00:00.510291, 1002714 pkts/sec analyzed
trace file elapsed time: 0:02:35.836372
TCP 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.dat
date segs bytes rexsegs rexbytes new active
--------------- -------- -------- -------- -------- -------- --------
16:58:50.244708 85055 4513418 0 0 6 6
16:59:05.244708 110921 5882896 0 0 0 2
16:59:20.244708 126107 6697827 0 0 1 3
16:59:35.244708 151719 8043597 0 0 0 2
16:59:50.244708 37296 1980557 0 0 0 3
17:00:05.244708 67 8828 0 0 2 3
17:00:20.244708 149 22053 0 0 1 2
17:00:35.244708 30 4080 0 0 0 1
17:00:50.244708 39 5688 0 0 0 1
17:01:05.244708 67 8828 0 0 2 3
17:01:11.081080 37 4121 0 0 1 3