Linux性能监测:监测目的与工具介绍
系统优化是一项复杂、繁琐、长期的工作,优化前需要监测、采集、测试、评估,优化后也需要测试、采集、评估、监测,而且是一个长期和持续的过程,不是说现在优化了,测试了,以后就可以一劳永逸了,也不是说书本上的优化就适合眼下正在运行的系统,不同的系统、不同的硬件、不同的应用优化的重点也不同、优化的方法也不同、优化的参数也不同。性能监测是系统优化过程中重要的一环,如果没有监测、不清楚性能瓶颈在哪里,优化什么呢、怎么优化呢?所以找到性能瓶颈是性能监测的目的,也是系统优化的关键。系统由若干子系统构成,通常修改一个子系统有可能影响到另外一个子系统,甚至会导致整个系统不稳定、崩溃。所以说优化、监测、测试通常是连在一起的,而且是一个循环而且长期的过程,通常监测的子系统有以下这些:
· CPU
· Memory
· IO
· Network
这些子系统互相依赖,了解这些子系统的特性,监测这些子系统的性能参数以及及时发现可能会出现的瓶颈对系统优化很有帮助。
应用类型
不同的系统用途也不同,要找到性能瓶颈需要知道系统跑的是什么应用、有些什么特点,比如 web server 对系统的要求肯定和 file server 不一样,所以分清不同系统的应用类型很重要,通常应用可以分为两种类型:
· IO 相关,IO 相关的应用通常用来处理大量数据,需要大量内存和存储,频繁 IO 操作读写数据,而对 CPU 的要求则较少,大部分时候 CPU 都在等待硬盘,比如,数据库服务器、文件服务器等。
· CPU 相关,CPU 相关的应用需要使用大量 CPU,比如高并发的 web/mail 服务器、图像/视频处理、科学计算等都可被视作 CPU 相关的应用。
看看实际中的例子,第1个是文件服务器拷贝一个大文件时表现出来的特征,第2个是 CPU 做大量计算时表现出来的特征:
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
0 4 140 1962724 335516 4852308 0 0 388 65024 1442 563 0 2 47 52 0
0 4 140 1960788 335516 4855300 0 0 768 48640 1412 573 0 1 50 49 0
0 5 140 1957488 335516 4858884 0 0 768 81412 1504 609 0 2 50 49 0
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
4 0 140 3625096 334256 3266584 0 0 0 16 1054 470 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 3624712 334264 3266580 0 0 0 80 1053 501 100 0 0 0 0
上面两个例子最明显的差别就是 id 一栏,代表 CPU 的空闲率,拷贝文件时候 id 维持在 50% 左右,CPU 大量计算的时候 id 基本为 0。
底线
我们如何知道系统性能是好还是差呢?这需要事先建立一个底线,如果性能监测得到的统计数据跨过这条线,我们就可以说这个系统性能差,如果数据能保持在线内我们就说性能好。建立这样底线需要知道一些理论、额外的负载测试和系统管理员多年的经验。如果自己没有多年的经验,有一个简单划底线的办法就是:把这个底线建立在自己对系统的期望上。自己期望这个系统有个什么样的性能,这是一个底线,如果没有达到这个要求就是性能差。比如,VPSee 上个月有个 RAID0 的测试,期望的测试结果应该是 RAID0 的 IO 性能比单硬盘有显著提高,底线是 RAID0 的 IO 至少要比单硬盘要好(好多少不重要,底线是至少要好),测试结果却发现 RAID0 性能还不如单硬盘,说明性能差,这个时候需要问个为什么,这往往是性能瓶颈所在,经过排查发现是原硬盘有硬件瑕疵造成性能测试结果错误。
监测工具
我们只需要简单的工具就可以对 Linux 的性能进行监测,以下是 VPSee 常用的工具:
工具 |
简单介绍 |
top |
查看进程活动状态以及一些系统状况 |
vmstat |
查看系统状态、硬件和系统信息等 |
iostat |
查看CPU 负载,硬盘状况 |
sar |
综合工具,查看系统状况 |
mpstat |
查看多处理器状况 |
netstat |
查看网络状况 |
iptraf |
实时网络状况监测 |
tcpdump |
抓取网络数据包,详细分析 |
mpstat |
查看多处理器状况 |
tcptrace |
数据包分析工具 |
netperf |
网络带宽工具 |
dstat |
综合工具,综合了 vmstat, iostat, ifstat, netstat 等多个信息 |
本系列将按照CPU、内存、磁盘IO、网络这几个方面分别介绍。
Linux性能监测:CPU篇
CPU 也是一种硬件资源,和任何其他硬件设备一样也需要驱动和管理程序才能使用,我们可以把内核的进程调度看作是 CPU 的管理程序,用来管理和分配 CPU 资源,合理安排进程抢占 CPU,并决定哪个进程该使用 CPU、哪个进程该等待。
CPU 的占用主要取决于什么样的资源正在 CPU 上面运行,比如拷贝一个文件通常占用较少 CPU,因为大部分工作是由 DMA(Direct Memory Access)完成,只是在完成拷贝以后给一个中断让 CPU 知道拷贝已经完成;科学计算通常占用较多的 CPU,大部分计算工作都需要在 CPU 上完成,内存、硬盘等子系统只做暂时的数据存储工作。要想监测和理解 CPU 的性能需要知道一些的操作系统的基本知识,比如:中断、进程调度、进程上下文切换、可运行队列等。这里 VPSee 用个例子来简单介绍一下这些概念和他们的关系,CPU 很无辜,是个任劳任怨的打工仔,每时每刻都有工作在做(进程、线程)并且自己有一张工作清单(可运行队列),由老板(进程调度)来决定他该干什么,他需要和老板沟通以便得到老板的想法并及时调整自己的工作(上下文切换),部分工作做完以后还需要及时向老板汇报(中断),所以打工仔(CPU)除了做自己该做的工作以外,还有大量时间和精力花在沟通和汇报上。
CPU 也是一种硬件资源,和任何其他硬件设备一样也需要驱动和管理程序才能使用,我们可以把内核的进程调度看作是 CPU 的管理程序,用来管理和分配 CPU 资源,合理安排进程抢占 CPU,并决定哪个进程该使用 CPU、哪个进程该等待。操作系统内核里的进程调度主要用来调度两类资源:进程(或线程)和中断,进程调度给不同的资源分配了不同的优先级,优先级最高的是硬件中断,其次是内核(系统)进程,最后是用户进程。每个 CPU都维护着一个可运行队列,用来存放那些可运行的线程。线程要么在睡眠状态(blocked 正在等待 IO)要么在可运行状态,如果 CPU 当前负载太高而新的请求不断,就会出现进程调度暂时应付不过来的情况,这个时候就不得不把线程暂时放到可运行队列里。VPSee 在这里要讨论的是性能监测,上面谈了一堆都没提到性能,那么这些概念和性能监测有什么关系呢?关系重大。如果你是老板,你如何检查打工仔的效率(性能)呢?我们一般会通过以下这些信息来判断打工仔是否偷懒:
· 打工仔接受和完成多少任务并向老板汇报了(中断);
· 打工仔和老板沟通、协商每项工作的工作进度(上下文切换);
· 打工仔的工作列表是不是都有排满(可运行队列);
· 打工仔工作效率如何,是不是在偷懒(CPU 利用率)。
现在把打工仔换成 CPU,我们可以通过查看这些重要参数:中断、上下文切换、可运行队列、CPU 利用率来监测 CPU 的性能。
底线
上一篇 Linux 性能监测:介绍 提到了性能监测前需要知道底线,那么监测 CPU 性能的底线是什么呢?通常我们期望我们的系统能到达以下目标:
· CPU 利用率,如果 CPU 有 100% 利用率,那么应该到达这样一个平衡:65%-70% User Time,30%-35% System Time,0%-5% Idle Time;
· 上下文切换,上下文切换应该和 CPU 利用率联系起来看,如果能保持上面的 CPU 利用率平衡,大量的上下文切换是可以接受的;
· 可运行队列,每个可运行队列不应该有超过1-3个线程(每处理器),比如:双处理器系统的可运行队列里不应该超过6个线程。
vmstat
vmstat 是个查看系统整体性能的小工具,小巧、即使在很 heavy 的情况下也运行良好,并且可以用时间间隔采集得到连续的性能数据。
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
2 1 140 2787980 336304 3531996 0 0 0 128 1166 5033 3 3 70 25 0
0 1 140 2788436 336304 3531996 0 0 0 0 1249 8036 5 4 67 25 0
3 1 140 2779292 336304 3531992 0 0 0 28 1323 7087 4 5 67 25 0
参数介绍:
· r,可运行队列的线程数,这些线程都是可运行状态,只不过 CPU 暂时不可用;
· b,被 blocked 的进程数,正在等待 IO 请求;
· in,被处理过的中断数
· cs,系统上正在做上下文切换的数目
· us,用户占用 CPU 的百分比
· sys,内核和中断占用 CPU 的百分比
· wa,所有可运行的线程被 blocked 以后都在等待 IO,这时候 CPU 空闲的百分比
· id,CPU 完全空闲的百分比
举两个现实中的例子来实际分析一下:
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
4 0 140 2915476 341288 3951700 0 0 0 0 1057 523 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 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个。
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
14 0 140 2904316 341912 3952308 0 0 0 460 1106 9593 36 64 1 0 0
20 0 140 2902016 341912 3952000 0 0 0 0 1046 9739 35 64 1 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个以内。
mpstat
mpstat 和 vmstat 类似,不同的是 mpstat 可以输出多个处理器的数据,下面的输出显示 CPU1 和 CPU2 基本上没有派上用场,系统有足够的能力处理更多的任务。
Linux 2.6.18-164.el5 (vpsee) 11/13/2009
02:24:33 PM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
02:24:34 PM 0 7.00 0.00 8.00 0.00 0.00 0.00 0.00 85.00 1001.00
02:24:34 PM 2 0.00 0.00 0.00 100.00 0.00 0.00 0.00 0.00 0.00
$ while :; do ps -eo pid,ni,pri,pcpu,psr,comm | grep 'firefox'; sleep 1; done
PID NI PRI %CPU PSR COMMAND
9846 0 24 8.8 0 firefox
9846 0 24 8.8 0 firefox
# /sbin/sysctl -n vm.dirty_background_ratio
# vmstat 1
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 2 253484 2216 228 7104 5368 2976 5372 3036 930 519 0 0 0 100 0
1 2 260008 2188 144 6824 11824 2584 12664 2584 1347 1174 14 0 0 86 0
$ /usr/bin/time -v date
Page size (bytes): 4096
$ /usr/bin/time -v date
Major (requiring I/O) page faults: 1
...
File Buffer Cache
从上面的内存缓存区(也叫文件缓存区 File Buffer Cache)读取页比从硬盘读取页要快得多,所以 Linux 内核希望能尽可能产生次缺页中断(从文件缓存区读),并且能尽可能避免主缺页中断(从硬盘读),这样随着次缺页中断的增多,文件缓存区也逐步增大,直到系统只有少量可用物理内存的时候 Linux 才开始释放一些不用的页。我们运行 Linux 一段时间后会发现虽然系统上运行的程序不多,但是可用内存总是很少,这样给大家造成了Linux 对内存管理很低效的假象,事实上 Linux 把那些暂时不用的物理内存高效的利用起来做预存(内存缓存区)呢。下面打印的是 VPSee 的一台Sun 服务器上的物理内存和文件缓存区的情况:
MemTotal: 8182776 kB
Buffers: 342704 kB
$ iostat -kx 1
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
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
$ iostat -kx 1
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
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
$ cat /proc/meminfo
MemFree: 2125476 kB
Cached: 4892024 kB
...
SwapFree: 4096424 kB
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
1 2 260008 2188 144 6824 11824 2584 12664 2584 1347 1174 14 0 0 86 0
# /sbin/ethtool eth0
Supported ports: [ TP ]
100baseT/Half 100baseT/Full
Supports auto-negotiation: Yes
100baseT/Half 100baseT/Full
Advertised auto-negotiation: Yes
Duplex: Full
PHYAD: 1
Auto-negotiation: on
Wake-on: g
Link detected: yes
上面给出的例子说明网卡有 10baseT,100baseT 和 1000baseT 三种选择,目前正自适应为 100baseT(Speed: 100Mb/s)。可以通过 ethtool 工具强制网卡工作在 1000baseT 下:
# iptraf -d eth0
netperf
netperf 运行在 client/server 模式下,比 iptraf 能更多样化的测试终端的吞吐量。先在服务器端启动 netserver:
Starting netserver at port 12865
# netperf -H 172.16.38.36 -l 10
Recv Send Send
Size Size Size Time Throughput
# netperf -t TCP_RR -H 172.16.38.36 -l 10 -- -r 2048,32768
Local /Remote
Send Recv Size Size Time Rate
16384 87380
iperf
iperf 和 netperf 运行方式类似,也是 server/client 模式,先在服务器端启动 iperf:
------------------------------------------------------------
TCP window size: 85.3 KByte (default)
Running Iperf Server as a daemon
# iperf -c 172.16.38.36 -t 30 -i 5
Client connecting to 172.16.38.36, TCP port 5001
------------------------------------------------------------
[ ID] Interval Transfer Bandwidth
[ ID] Interval Transfer Bandwidth
[ ID] Interval Transfer Bandwidth
[ ID] Interval Transfer Bandwidth
[ ID] Interval Transfer Bandwidth
[ ID] Interval Transfer Bandwidth
[ ID] Interval Transfer Bandwidth
# /usr/sbin/tcpdump -w network.dmp
511942 packets captured
0 packets dropped by kernel
# tcptrace network.dmp
Ostermann's tcptrace -- version 6.6.7 -- Thu Nov 4, 2004
511677 packets seen, 511487 TCP packets traced
trace file elapsed time: 0:02:35.836372
1: zaber:54581 - boulder:111 (a2b) 6> 5< (complete)
3: zaber:pcanywherestat - 172.16.39.5:53086 (e2f) 2> 3<
5: 172.16.39.100:58029 - zaber:12865 (i2j) 7> 5< (complete)
7: breakpoint:45510 - zaber:7012 (m2n) 9> 5< (complete)
9: zaber:837 - boulder:32774 (q2r) 6> 5< (complete)
11: zaber:59362 - boulder:111 (u2v) 6> 5< (complete)
13: breakpoint:45512 - zaber:7012 (y2z) 9> 5< (complete)
tcptrace 功能很强大,还可以通过过滤和布尔表达式来找出有问题的连接,比如,找出转播大于100 segments 的连接:
# tcptrace -o10 network.dmp
下面的命令使用 tcptrace 的 slice 模式,程序自动在当前目录创建了一个 slice.dat 文件,这个文件包含了每隔15秒的转播信息:
date segs bytes rexsegs rexbytes new active
16:58:50.244708 85055 4513418 0 0 6 6
16:59:20.244708 126107 6697827 0 0 1 3
16:59:50.244708 37296 1980557 0 0 0 3
17:00:20.244708 149 22053 0 0 1 2
17:00:50.244708 39 5688 0 0 0 1
17:01:11.081080 37 4121 0 0 1 3