标签:
目录[-]
系统优化是一项复杂、繁琐、长期的工作,优化前需要监测、采集、测试、评估,优化后也需要测试、采集、评估、监测,而且是一个长期和持续的过程,不 是说现在优化了,测试了,以后就可以一劳永逸了,也不是说书本上的优化就适合眼下正在运行的系统,不同的系统、不同的硬件、不同的应用优化的重点也不同、 优化的方法也不同、优化的参数也不同。性能监测是系统优化过程中重要的一环,如果没有监测、不清楚性能瓶颈在哪里,怎么优化呢?所以找到性能 瓶颈是性能监测的目的,也是系统优化的关键。系统由若干子系统构成,通常修改一个子系统有可能影响到另外一个子系统,甚至会导致整个系统不稳定、崩溃。所 以说优化、监测、测试通常是连在一起的,而且是一个循环而且长期的过程,通常监测的子系统有以下这些:
• CPU
• Memory
• IO
• Network
这些子系统互相依赖,了解这些子系统的特性,监测这些子系统的性能参数以及及时发现可能会出现的瓶颈对系统优化很有帮助。
应用类型
不同的系统用途也不同,要找到性能瓶颈需要知道系统跑的是什么应用、有些什么特点,比如 web server 对系统的要求肯定和 file server 不一样,所以分清不同系统的应用类型很重要,通常应用可以分为两种类型:
• IO 相关,IO 相关的应用通常用来处理大量数据,需要大量内存和存储,频繁 IO 操作读写数据,而对 CPU 的要求则较少,大部分时候 CPU 都在等待硬盘,比如,数据库服务器、文件服务器等。
• CPU 相关,CPU 相关的应用需要使用大量 CPU,比如高并发的 web/mail 服务器、图像/视频处理、科学计算等都可被视作 CPU 相关的应用。
监测工具
我们只需要简单的工具就可以对 Linux 的性能进行监测,以下是 VPSee 常用的工具:
工具 简单介绍
top 查看进程活动状态以及一些系统状况
vmstat 查看系统状态、硬件和系统信息等
iostat 查看CPU 负载,硬盘状况
sar 综合工具,查看系统状况
mpstat 查看多处理器状况
netstat 查看网络状况
iptraf 实时网络状况监测
tcpdump 抓取网络数据包,详细分析
tcptrace 数据包分析工具
netperf 网络带宽工具
dstat 综合工具,综合了 vmstat, iostat, ifstat, netstat 等多个信息
本系列将按照CPU、内存、磁盘IO、网络这几个方面分别介绍。
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 的情况下也运行良好,并且可以用时间间隔采集得到连续的性能数据。
举两个现实中的例子来实际分析一下:
1
2
3
4
5
6
7
8
|
$ 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
2
3
4
5
6
7
8
|
$ 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 |
2. 进一步观察发现 system time(sy)很高而 user time(us)很低,而且加上高频度的上下文切换(cs),说明正在运行的应用程序调用了大量的系统调用(system call);
3. run queue(r)在14个线程以上,按照这个测试机器的硬件配置(四核),应该保持在12个以内。
参数介绍:
• r,可运行队列的线程数,这些线程都是可运行状态,只不过 CPU 暂时不可用;
• b,被 blocked 的进程数,正在等待 IO 请求;
• in,被处理过的中断数
• cs,系统上正在做上下文切换的数目
• us,用户占用 CPU 的百分比
• sys,内核和中断占用 CPU 的百分比
• wa,所有可运行的线程被 blocked 以后都在等待 IO,这时候 CPU 空闲的百分比
• id,CPU 完全空闲的百分比
mpstat
mpstat 和 vmstat 类似,不同的是 mpstat 可以输出多个处理器的数据,下面的输出显示 CPU1 和 CPU2 基本上没有派上用场,系统有足够的能力处理更多的任务。
1
2
3
4
5
6
7
8
9
|
$ mpstat -P ALL 1 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 all 5.26 0.00 4.01 25.06 0.00 0.00 0.00 65.66 1446.00 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 1 13.00 0.00 8.00 0.00 0.00 0.00 0.00 79.00 444.00 02:24:34 PM 2 0.00 0.00 0.00 100.00 0.00 0.00 0.00 0.00 0.00 02:24:34 PM 3 0.99 0.00 0.99 0.00 0.00 0.00 0.00 98.02 0.00 |
ps
如何查看某个程序、进程占用了多少 CPU 资源呢?下面是 Firefox 在 VPSee 的一台 Sunray 服务器上的运行情况,当前只有2个用户在使用 Firefox:
1
2
3
4
5
6
7
|
$ while :; do ps -eo pid,ni,pri,pcpu,psr, comm | grep ‘firefox‘ ; sleep 1; done PID NI PRI %CPU PSR COMMAND 7252 0 24 3.2 3 firefox 9846 0 24 8.8 0 firefox 7252 0 24 3.2 2 firefox 9846 0 24 8.8 0 firefox 7252 0 24 3.2 2 firefox |
这里的讲到的 “内存” 包括物理内存和虚拟内存,虚拟内存(Virtual Memory)把计算机的内存空间扩展到硬盘,物理内存(RAM)和硬盘的一部分空间(SWAP)组合在一起作为虚拟内存为计算机提供了一个连贯的虚拟内 存空间,好处是我们拥有的内存 ”变多了“,可以运行更多、更大的程序,坏处是把部分硬盘当内存用整体性能受到影响,硬盘读写速度要比内存慢几个数量级,并且 RAM 和 SWAP 之间的交换增加了系统的负担。
在操作系统里,虚拟内存被分成页,在 x86 系统上每个页大小是 4KB。Linux 内核读写虚拟内存是以 “页” 为单位操作的,把内存转移到硬盘交换空间(SWAP)和从交换空间读取到内存的时候都是按页来读写的。内存和 SWAP 的这种交换过程称为页面交换(Paging),值得注意的是 paging 和 swapping 是两个完全不同的概念,国内很多参考书把这两个概念混为一谈,swapping 也翻译成交换,在操作系统里是指把某程序完全交换到硬盘以腾出内存给新程序使用,和 paging 只交换程序的部分(页面)是两个不同的概念。纯粹的 swapping 在现代操作系统中已经很难看到了,因为把整个程序交换到硬盘的办法既耗时又费力而且没必要,现代操作系统基本都是 paging 或者 paging/swapping 混合,swapping 最初是在 Unix system V 上实现的。
虚拟内存管理是 Linux 内核里面最复杂的部分,要弄懂这部分内容可能需要一整本书的讲解。VPSee 在这里只介绍和性能监测有关的两个内核进程:kswapd 和 pdflush。
• kswapd daemon 用来检查 pages_high 和 pages_low,如果可用内存少于 pages_low,kswapd 就开始扫描并试图释放 32个页面,并且重复扫描释放的过程直到可用内存大于 pages_high 为止。扫描的时候检查3件事:1)如果页面没有修改,把页放到可用内存列表里;2)如果页面被文件系统修改,把页面内容写到磁盘上;3)如果页面被修改 了,但不是被文件系统修改的,把页面写到交换空间。
• pdflush daemon 用来同步文件相关的内存页面,把内存页面及时同步到硬盘上。比如打开一个文件,文件被导入到内存里,对文件做了修改后并保存后,内核并不马上保存文件到硬 盘,由 pdflush 决定什么时候把相应页面写入硬盘,这由一个内核参数 vm.dirty_background_ratio 来控制,比如下面的参数显示脏页面(dirty pages)达到所有内存页面10%的时候开始写入硬盘。
1
2
|
# /sbin/sysctl -n vm.dirty_background_ratio 10 |
1
2
3
4
5
6
7
8
|
# 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
2
3
4
|
$ /usr/bin/time - v date ... Page size (bytes): 4096 ... |
1
2
3
4
5
|
$ /usr/bin/time - v date ... Major (requiring I /O ) page faults: 1 Minor (reclaiming a frame) page faults: 260 ... |
1
2
3
4
5
|
$ cat /proc/meminfo MemTotal: 8182776 kB MemFree: 3053808 kB Buffers: 342704 kB Cached: 3972748 kB |
1
2
3
4
5
6
7
8
9
10
11
12
|
$ 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 |
1
2
3
4
5
6
7
8
9
10
11
12
|
$ 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 |
1
2
3
4
5
6
7
8
9
10
|
$ cat /proc/meminfo MemTotal: 8182776 kB MemFree: 2125476 kB Buffers: 347952 kB Cached: 4892024 kB SwapCached: 112 kB ... SwapTotal: 4096564 kB SwapFree: 4096424 kB ... |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# /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 |
1
2
|
# /sbin/ethtool -s eth0 speed 1000 duplex full autoneg off iptraf |
1
|
# iptraf -d eth0 |
1
2
3
|
# netserver Starting netserver at port 12865 Starting netserver at hostname 0.0.0.0 port 12865 and family AF_UNSPEC |
1
2
3
4
5
6
7
8
|
# 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 |
1
2
3
4
5
6
7
8
9
|
# 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 |
1
2
3
4
5
6
7
|
# 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 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
# 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 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
# /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) |
1
|
# tcptrace -f‘rexmit_segs>100‘ network.dmp |
1
|
# tcptrace -o10 network.dmp |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# 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 |
标签:
原文地址:http://www.cnblogs.com/sysk/p/4821792.html