原文地址:http://kerrigan.sinaapp.com/post-7.html
Linux System and Performance Monitoring
http://www.houstondad.com/papers/oscon2009-linux-monitoring.pdf
Darren Hoch
译:Roger
这是[叔度]给我的一篇非常不错的关于Linux性能监控的文档,可惜是英文的,网上只能找到些中文节选,并不完整。
准备花些时间将原文共43页认真学习一下,顺便翻译分享给大家。当然,还是推荐阅读英文文档,要么使用google翻译,最后再考虑读这篇。:)
Linux系统与性能监控
目录
性能优化是找到并消除系统瓶颈的过程。很多系统管理员觉得性能优化能通过学习一本“cookbook”实现,也就是说设置一些内核参数就能简单地解决问题。事实上并不是这样。性能优化实际上是为了在操作系统下的不同子系统之间获得平衡。这些子系统包括:
这些子系统相互之间高度依赖。任何一个子系统的高负载都会引起其它子系统出现问题。例如:
为了优化系统,我们必须定位瓶颈在哪。即使问题看起来像是某个子系统引起,也有可能是因为其它子系统高负载导致。
为了明白从哪里开始优化瓶颈,首要工作就是分析目前系统的行为特点。任何系统的应用通常分为如下两类:
确定统计基线
系统使用率离不开系统管理员期望的效果和系统的规格。了解系统性能是否有问题的唯一方式是明确系统能达到的效果。应该有怎样的表现,参考值应该是什么?唯一方法就是建立一个基线。数据必须在系统性能可以接受的情况下统计,这样才能和性能不可接受的情况下进行对比。
在下面的例子中,基线的系统性能截图和高负荷的系统性能截图进行对比。
# 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
仅仅看最后一列(id),它代表空闲时间,我们可以看到再基线的状况下,CPU在79% - 100%的时间是空闲的。在第二个输出里,CPU有100%的使用率而且没有空闲。我们需要确定是否对系统的CPU使用率进行优化。
绝大多数类Unix系统都有一系列标准的监控命令。它们从最开始就是类Unix系统的一部分。这些监控工具在Linux的基本安装包或额外安装包里就提供了。基本上所有的发行版都有这些工具。尽管有很多开源或第三方工具,但这篇文章的主要介绍使用发行版中自带的工具。
表格1:性能监控工具
CPU的使用率很大程度上取决于它尝试访问什么资源。内核通过调度器来调度两种类型的资源:线程(单个或多个)和中断。调度器对不同资源给予不同的优先级。下面按从高到低的顺序列出了优先级。
为了理解内核怎样管理不同的资源,需要介绍一些关键概念。下面章节介绍了上下文切换,运行队列和使用率。
大多数现代处理器在同一时间只能运行一个进程(单线程)或线程。多路超线程处理器可以在同一时间运行多条线程。但Linux内核仍然把双核处理器每个核心当作独立的处理器。例如,一个拥有双核处理器的系统,Linux内核显示为有两个独立的处理器。
一个标准的Linux内核可以同时运行50到50,000个处理线程。在一个CPU上,内核需要调度各个处理线程的平衡。每个线程拥有处理 器分配给它的时间片额度,一旦某个线程的时间片用完或者被某个更高优先级(例如硬中断)取代,这个线程就被重新放回队列中,更高优先级的线程将占据处理 器。这种线程间的切换关系就被称为上下文切换。
内核每次处理上下文切换,就有资源开销用来把线程从CPU寄存器中移除并放置到队列中。系统中上下文切换越频繁,内核就需要在管理调度处理器上做更多的工作。
每个CPU维护着线程的运行队列。理想情况下,调度器应该不断运行并执行线程。处理线程要么是在睡眠状态(阻塞并且等待IO),要么是在可运行状 态。如果CPU子系统高负荷,很有可能内核调度器不能及时响应系统请求。结果造成可运行的进程开始阻塞队列。队列越大,处理线程需要等待的时间越长。
一个非常流行的术语称为“load”,它通常用来描诉运行队列的状态。系统的负载值是由当前正在执行的线程数和CPU队列中的线程数相加得 到。比如2个线程正在双核处理器系统中运行,同时有4个线程在等待队列里,那么它的负载就是6。top这类工具报告了负载在1,5和15分钟内的负载平均值。
CPU使用率定义了CPU使用情况的百分比。CPU的使用率是用来评估系统的一个重要度量值。绝大多数性能监控工具把CPU使用率归到以下几类。
了解CPU到底表现如何,重在理解运行队列,使用率和上下文切换的性能。像之前提到的,性能是相对于基线数据的。但是在任何系统中都有一些基本的性能预期。这些预期包括:
Linux下有很多工具可以度量这些统计数据,首先介绍的两个就是vmstat和top。
vmstat工具提供了一个优秀且低开销的系统性能展示。正由于vmstat是如此一个低开销的工具,让它在控制台持续运行非常实用,即使你需要在 一台负载很高的服务器上监控健康状况。vmstat有两种工作模式,平均模式和简单模式。简单模式将在指定的间隔里统计数据,这个模式用来在有持续的负载 时了解性能参数最有用。下面例子示范了vmstat运行在1秒间隔里。
# 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
输出里每个字段的解释如下:
表格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
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
通过观察输出,我们可以得出以下结论:
在下面的案例中,内核调度器已经饱和了,它全部用来处理上下文切换。
# 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
1
通过观察输出,我们可以得出以下结论:
如果你的系统有多核处理器,可以使用mpstat来监控每个独立的核心。Linux内核把双核处理器当做两个CPU,同样,四核处理器也被认为是4个CPU可用。mpstat像vmstat一样提供CPU的使用率,但mpstat单独统计出每个核心的基础数据。
# 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个CPU核心可用,其中两个CPU在处理进程,使用率被完全占满(CPU0和CPU1)。第三个核心在处理所有的内核和系统调用(CPU3)。第四个核心是空闲状态。 top命令显示有3个进程正完全占满CPU使用率。
# 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,通过PSR这一列可以看出(译:PSR这一列表明目前第几个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
总结
监控CPU性能由以下几部分组成。
虚拟内存把磁盘当作内存的扩展,可以有效地提高可用内存的容量。内核将当前不使用的内存块写入磁盘,空出来的内存空间便可以做其它用途。当需要之前 的内存数据时,内核就将它们读回到内存。这一切对用户而言都是透明的。在Linux下运行的程序只能看到大量的可用内存,并不能注意到它们偶尔是驻留在磁 盘上的。当然,和使用内存相比,读写磁盘会更慢一些(大约慢几千倍),因此程序没法快速执行。磁盘上当作虚拟内存使用的部分称为交换空间。
虚拟内存被分割成页,页是内存管理的基本单位。在X86架构下,每个虚拟内存页是4KB。当内核写内存到磁盘或从磁盘读回内存,也是以页来管理。内核写内存页时,既写到磁盘交换设备里,又写到文件系统中。
内核分页调度是一个普通的活动,不要把它和内存与虚拟内存之间的交换弄混淆了。内存分页调度是进程在通常的间隔时间里同步内存里的数据到磁盘里。随着时间的推移,应用程序会消耗所有的内存。某些情况下,内核必须扫描内存然后回收未使用的页,这样才能为其它的应用程序分配内存。
页框回收算法用来释放内存。它根据页的类型来选择是否释放内存。类型如下:
除了“不可回首页”以外,其它的可能被页框回收算法回收。
页框回收算法主要有两个功能,它们是kswapd线程和“LMR算法”函数。
kswapd守护进程负责保证内存空余空间。它监控内核中的pages_high和pages_low阀值。如果可用内存的大小低于pages_low,kswapd进程开始扫描并尝试一次回收32页。它不断重复直到内存大小超过pages_high阀值。
kswapd线程完成下列工作:
[sk@SK:~]$
ps
-ef
|
grep
kswapd
root 25
2 0 09:33
? 00:00:02
[kswapd0]
sk 11245 3752 0
17:21
pts
/0
00:00:00
grep
--color=auto
kswapd
<font color=
"#000000"
>
<
/font
>
pdflush守护进程负责将关系到文件系统的页同步到磁盘。换句话说,当一个文件在内存中被使用,pdflush守护进程把它写回磁盘。
[roger@xxx:~]$
ps
-ef
|
grep
pdflush
root 1624 35 0 Aug24
? 00:00:34 [pdflush]
roger 5110 4935 0 17:26
pts
/198
00:00:00
grep
pdflush
root 23547 35 0 Aug23
? 00:00:27 [pdflush]
<font style=
"font-size:
9.8pt"
>当内存中有10%的脏页时,pdflush守护进程开始同步脏页到文件系统。这个数值可以通过内核参数vm.dirty_background_ratio来调整。<
/font
>
[root@SK sk]
# sysctl -n
vm.dirty_background_ratio
10
pdflush守护进程在大多数情况下与PFRA是独立工作的。当内核调用LMR算法时,除了其它的常规页释放以外,LMR特别强制pdflush写脏页。
在2.4的内核里,如果内存负载压力很大。系统可能造成swap失效。这在PFRA准备偷一个活动进程正准备要使用的页时发生。结果,进程 不得不回收这个页,而它会被再次偷取。这在2.6的内核中通过“Swap Token”修复,它禁止PFRA不断地从一个进程偷取同一个页。(译注:swapout protection token(swap token)防止页面“抖动”)
vmstat工具除了显示CPU使用率,也显示虚拟内存的使用情况。接下来介绍vmstat输出与虚拟内存有关的部分。
表格2:虚拟内存的统计信息
下面vmstat输出表明在IO应用程序的峰值情况下,虚拟内存有很高的使用率。
<font style=
"font-size:
9.8pt"
><font
color=
"#000000"
size=
"2"
>#
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<
/font
><
/font
>
我们能从上面输出观察到以下几点:
虚拟内存性能监控包括下面这些部分:
磁盘I/O子系统在任何Linux系统里都是最慢的。这主要是因为磁盘离CPU距离较远和磁盘物理上的工作方式(轮转和寻道)决定的。如果将访问磁 盘和访问内存的时间转换成分钟和秒进行对比,那就是7天和7分钟的区别。因此,Linux内核将在磁盘上产生的I/O最小化就是非常有必要的。下面的小节 描述了内核处理内存和磁盘之间数据I/O的相互交换的不同方式。
Linux内核将磁盘I/O分割成页。在绝大多数Linux系统上,默认的页大小是4K。它以4K为页大小读写磁盘块到内存或出内存。你可以通过time命令来查看页大小,在详尽(verbose)模式中搜索页大小。
<font
color=
"#000000"
>[sk@SK:~]$
/usr/bin/time
-
v
date
<snip>
Page size (bytes): 4096
<snip><
/font
>
Linux,类似于其它Unix系统,使用虚拟内存层映射到物理地址空间。当一个进程启动的时候,这个映射是“被要求”产生的,内核只映射那些需要 的部分。在进程开始的时候,内核搜索CPU缓存和物理内存。如果数据都不存在,内核抛出主页错误的异常(MPF)。MPF是一个请求到磁盘子系统来检索磁 盘找回页并缓存到RAM里。
一旦内存页映射成缓存,内核尝试在小页错误(MnPF)里使用这些页。MnPF节约内核时间,通过重新使用内存里的一个页而不是把它放到磁盘里。
在下面的例子中,time命令用来显示当一个应用启动的时候,有多少MPF和MnPF产生了。应用程序第一次启动的时候,会有很多MPF。
<font
color=
"#000000"
>[sk@SK:~]$
/usr/bin/time
-
v
audacious
<snip>
Major (requiring I
/O
) page
faults: 93
Minor (reclaiming a frame) page faults:
3844
<snip><
/font
>
第二次启动的时候,内核没有抛出任何MPF,因为应用程序已经在内存里了。
<font
color=
"#000000"
>[sk@SK:~]$
/usr/bin/time
-
v
audacious
<snip>
Major (requiring I
/O
) page
faults: 0
Minor (reclaiming a frame) page faults:
3913
<snip>
<
/font
>
文件缓冲区缓存是内核用来最小化MPF并且最大化MnPF的。随着系统产生I/O请求,缓存将持续增大,系统将在内存中保存这些页,直到内存容量很 低并且内核需要释放一些页保留作其它用途。最后导致一些系统管理员看见可用内存很少并开始担心什么时候出现这个问题,其实系统仅仅是充分利用内存,将它们 缓存起来了。
下面的输出是从/proc/meminfo中取出的:
<font
color=
"#000000"
>[sk@SK:~]$
cat
/proc/meminfo
MemTotal: 2015244
kB
MemFree:
191648 kB
Buffers:
16284 kB
Cached:
590536 kB
<snip><
/font
>
系统一共有2GB(MemTotal)物理内存。当前还剩191MB(MemFree)空余内存。16MB分配给磁盘进行写操作(Buffers),590MB的页从磁盘读到内存里(Caches)。
内核使用内存是通过MnPF机制,以此来避免从磁盘中拿出所有的页。由于我们只有这部分统计数据,因此无法得知系统是否在重负荷状况下。
Linux内核有三种类型的的内存页,下面我们会逐个讨论:
应用程序可能自己选择使用fsync()或sync()系统调用立刻写脏页到磁盘。这些系统调用向I/O调度器发送一个直接请求。如果应用程序并不请求系统调用,pdflush内核守护进程会每隔一段时间周期性地运行把页写回磁盘。
<font
color=
"#000000"
>[roger@xxx:~]$
ps
-ef
|
grep
pdflush
root 1624 35 0 Aug24
? 00:00:44 [pdflush]
roger 16085 14515 0 22:31
pts
/51
00:00:00
grep
pdflush
root 23547 35 0 Aug23
? 00:00:35
[pdflush]<
/font
>
某些情况下也会产生I/O的瓶颈。这些情况能通过一系列的标准的系统监控工具看出来。这些工具包括top, vmstat, iostat和sar。这些命令的输出有些会比较类似,但大部分情况是:每种工具都提供了某些性能指标的唯一输出。下面这些子章节描述了产生I/O瓶颈的 情况。
每一个到磁盘的I/O请求都会需要一定的时间。这主要是因为磁盘必须旋转而且磁头必须寻道。磁盘的旋转经常会提到“旋转延迟(rotational delay)”(RD)和移动磁头“磁头寻道(disk seek)”(DS)。每一个I/O请求所花的时间是由DS和RD计算得来。一个磁盘的RD基于每分钟磁盘的转速(RPM)。通常我们认为RD是磁盘旋转 一圈的时间的一半。下面我们来计算一个万转(10K RPM)磁盘的RD:
每当应用程序请求一次I/O,如果是万转磁盘(10k RPM)平均花费8毫秒在I/O上。虽然这是一个定值,但对磁盘读写所花费的时间来说,它是重要的性能指标。I/O请求量经常通过每秒I/O(IOPS) 来测量。10K RPM 磁盘有能力达到120至150(突发)IOPS。为了测量IOPS的有效性,将IOPS分成读/写两种IOPS。
每个I/O所产生的效果依赖于系统的工作负载。系统里有两种工作负载,顺序I/O和随机I/O。
iostat命令提供了IOPS的信息和每个I/O在被处理的数据量。使用 -x 来显示扩展信息。顺序的工作负载需要一次性地顺序读取大量的数据。这些应用类似企业级的数据库执行大量的查询和流媒体服务正在采集数据。在顺序工作负载 里,每个I/O包含的KB数会很高。顺序的工作负载的性能依赖于尽可能快地搬运大量数据的能力。如果每个I/O花费时间,尽可能多地在每个I/O里取出数 据就非常重要。
<font style=
"font-size:
9.8pt"
><font
color=
"#000000"
size=
"2"
>#
iostat -x 1
avg-cpu: %user %
nice
%sys
%idle
0.00 0.00 57.1 4 42.86
Device:
rrqm
/s
wrqm
/s
r
/s
w
/s
rsec
/s
wsec
/s
rkB
/s
wkB
/s
avgrq-sz
avgqu-sz await svctm %util
/dev/sda
0.00 12891.43 0.00 105.71
0.00 106080.00 0.00 53040.00 1003.46 1099.43
3442.43 26.49 280.00
/dev/sda1
0.00
0.00 0.00 0.00 0.00
0.00 0.00 0.00
0.00 0.00
0.00 0.00 0.00
/dev/sda2
0.00 12857.14 0.00
5.71 0.00 105782.86 0.00 52891.43 18512.00
559.14 780.00 490.00 280.00
/dev/sda3
0.00
34.29 0.00 100.00 0.00
297.14 0.00 148.57
2.97 540.29 3594.57 24.00
240.00
avg-cpu: %user %
nice
%sys
%idle
0.00 0.00 23.53 76.47
Device:
rrqm
/s
wrqm
/s
r
/s
w
/s
rsec
/s
wsec
/s
rkB
/s
wkB
/s
avgrq-sz
avgqu-sz await svctm %util
/dev/sda
0.00 17320.59 0.00 102.94
0.00 142305.88 0.00 71152.94 1382.40 6975.29
952.29 28.57 294.12
/dev/sda1
0.00
0.00 0.00 0.00 0.00
0.00 0.00 0.00
0.00 0.00 0.00
0.00 0.00
/dev/sda2
0.00 16844.12 0.00 102.94
0.00 138352.94 0.00 69176.47 1344.00 6809.71
952.29 28.57 294.12
/dev/sda3
0.00 476.47
0.00 0.00 0.00 952.94 0.00
1976.47 0.00 165.59
0.00 0.00
276.47<
/font
><
/font
>
计算IOPS的效率的方式是用读的KB数(rkB/s)和写的KB数(wkB/s)除以每秒读的次数(r/s)和写的次数(w/s)。在上面的输出中,/dev/sda的每个I/O写的数据量逐渐递增:
随机访问工作负载对数据的大小依赖并不多。它们主要依赖于磁盘能达到的IOPS数。Web服务器和电子邮件服务器是随机访问工作负载的例子。每个I/O请求都非常小。随机访问工作负载依赖于一次能处理多少请求。因此,磁盘能达到的IOPS数就是关键因素。
<font color=
"#000000"
>avg-cpu:
%user %
nice
%sys %idle
2.04 0.00 97.96 0.00
Device:
rrqm
/s
wrqm
/s
r
/s
w
/s
rsec
/s
wsec
/s
rkB
/s
wkB
/s
avgrq-sz
avgqu-sz await svctm %util
/dev/sda
0.00 633.67
3.06 102.31 24.49 5281.63 12.24 2640.82
288.89 73.67 113.89 27.22 50.00
/dev/sda1
0.00 5.10
0.00 2.04 0.00 57.14
0.00 28.57 28.00
1.12 55.00 55.00 11.22
/dev/sda2
0.00 628.5 7 3.06
100.27 24.49 5224.49 12.24 2612.24 321.50
72.55 121.25 30.63 50.00
/dev/sda3
0.00 0.00
0.00 0.00 0.00 0.00
0.00 0.00 0.00
0.00 0.00 0.00 0.00
avg-cpu: %user %
nice
%sys
%idle
2.15 0.00 97.85 0.00
Device:
rrqm
/s
wrqm
/s
r
/s
w
/s
rsec
/s
wsec
/s
rkB
/s
wkB
/s
avgrq-sz
avgqu-sz await svctm %util
/dev/sda
0.00 41.94 6.45
130.98 51.61 352.69 25.81 3176.34 19.79
2.90 286.32 7.37 15.05
/dev/sda1
0.00 0.00
0.00 0.00 0.00 0.00 0.00
0.00 0.00
0.00 0.00 0.00 0.00
/dev/sda2
0.00 41.94 4.30
130.98 34.41 352.69 17.20 3176.34 21.18
2.90 320.00 8.24 15.05
/dev/sda3
0.00 0.00
2.15 0.00 17.20 0.00 8.60
0.00 8.00
0.00 0.00 0.00
0.00<
/font
>
前面的输出显示了写的IOPS数量和之前的顺序写的输出差不多。不同之处是每个I/O实际写的大小。
如果系统没有足够的内存来容纳所有的请求,就必须开始使用swap设备。就像磁盘I/O一样,写到swap设备需要些开销。如果系统完全没有了内 存,就可能产生换页风暴到swap磁盘上。如果swap设备和系统正尝试访问的数据在同一个文件系统上,系统将进入I/O路径的竞争。这会造成系统性能的 完全崩溃。如果页不能读或写到磁盘,会在内存中呆更久。如果呆更久,内核就需要释放内存。问题是I/O通道如此阻塞,什么都做不了。最终不可避免地造成 kernel panic和系统崩溃。
下面的vmstat输出展示了系统在缺乏内存的情况。它把数据写到swap设备里。
<font color=
"#000000"
>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<
/font
>
前面的输出显示了大量的到内存的读请求(bi)。由于请求太多,系统内存不足(free)。这造成系统把块写入swap设备(so)因此swap的大小不停增长(swpd)。同时注意到大量的IO等待时间百分比(wa)。这证明CPU由于I/O请求变慢。
查看由于使用swap给磁盘造成的影响,用iostat命令查看swap所在的设备。
<font color=
"#000000"
># iostat -x
1
avg-cpu: %user %
nice
%sys
%idle
0.00 0.00 100.00 0.00
Device:
rrqm
/s
wrqm
/s
r
/s
w
/s
rsec
/s
wsec
/s
rkB
/s
wkB
/s
avgrq-sz
avgqu-sz await svctm %util
/dev/sda
0.00 1766.67 4866.67
1700.00 38933.33 31200.00 19466.67 15600.00 10.68
6526.67 100.56 5.08 3333.33
/dev/sda1
0.00 933.33
0.00 0.00 0.00
7733.33 0.00 3866.67
0.00 20.00 2145.07 7.37
200.00
/dev/sda2
0.00
0.00 4833.33 0.00 38666.67
533.33 19333.33 266.67
8.11 373.33 8.07
6.90 87.00
/dev/sda3
0.00 833.33
33.33 1700.00 266.67 22933.33 133.33
11466.67 13.38 6133.33 358.46 11.35
1966.67<
/font
>
在前面的例子中,swap设备(/dev/sda1)和文件系统设备(/dev/sda3)在竞争I/O。它们都有大量的每秒写请求(w/s)和高等待时间(await)低服务时间率(svctm)。这证明两个分区之间有竞争,造成共同的性能下降。
I/O性能监控包含下面工作:
在所有的子系统监控里,网络是最难监控的。这主要是由于网络非常抽象。在开始监控性能的时候,会有很多因素在系统能控制的范围之上。这些因素包括延迟,冲突,拥塞和坏包,还有其它一些。
本章节关注怎样检查以太网,IP和TCP。
除非明确指定,所有以太网自适应速度。在历史上,这样做有大量的好处,尤其是网络上各种设备,各种速度和双工模式。
大多数企业的网络运行在100或1000BaseTX。使用ethtool来确定特指定的系统协商用的这个速度。
在下面的例子中,一个系统使用的100BaseTX网卡运行在自适应的10BaseT下。
<font
color=
"#000000"
>#
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
<
/font
>
下面的例子展示了怎样强制指定网卡运行在100BaseTX:
<font style=
"font-size:
9.8pt"
><font
color=
"#000000"
>#
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
<
/font
><
/font
>
一个网卡仅仅同步成功并不代表它没有带宽的问题。把交换机,网线和路由器摆放在两个主机系统之间测试,这是不现实的。检查网络吞吐量最好的方法是在两个系统之间传输数据,然后测量类似于延迟和速度这样的统计数据。
iptraf工具(http://iptraf.seul.org) 提供每个网卡吞吐量的仪表盘。
<font color=
"#000000"
># iptraf -d
eth0<
/font
>
前面的输出显示系统测试正在使用61mbps(7.65MB)的速率传输。这对一个100mps的网络来说,实在很慢。
不像iptraf这种被动的网卡流量监控方式,netperf工具允许系统管理员进行网络吞吐量的控制调整测试。这对确定网络之间的吞吐量非常有效,例如从一个客户端工作站到一个高负载的服务器例如文件或web服务器。netperf运行在客户端-服务端模式。
<font color=
"#000000"
>server#
netserver
Starting netserver at port 12865
Starting netserver
at
hostname
0.0.0.0 port 12865 and
family AF_UNSPEC<
/font
>
netperf能进行多种多样的测试。最基本测试是标准的吞吐量测试。下面的测试是从客户端发起一个在以太网上的30秒的TCP吞吐量测试。
输出显示网络的吞吐量在89mbps左右。服务器(192.168.1.215)是在同样的以太网。这对一个100mbps的网络来说,性能非常不错了。
<font color=
"#000000"
>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<
/font
>
离开局域网,换成54G的无线网络,离路由器10英尺远。输出的吞吐量明显下降。理论速度是54MBits,笔记本只达到了14MBits的吞吐量。
<font style=
"font-size:
9.8pt"
><font
color=
"#000000"
>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<
/font
><
/font
>
在50英尺远的地方,并且下了一个楼层,信号下降到5MBits。
<font style=
"font-size:
9.8pt"
><font
color=
"#000000"
># 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<
/font
><
/font
>
这次我们接到公共的互联网上,吞吐量掉到了1Mbit以下。
<font style=
"font-size:
9.8pt"
><font
color=
"#000000"
># 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<
/font
><
/font
>
最后的测试是VPN连接,在所有网络里面它是最差的吞吐量。
<font style=
"font-size:
9.8pt"
><font
color=
"#000000"
># 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<
/font
><
/font
>
另一个很有用的测试是使用netperf监控每秒能处理的TCP的请求和应答的数量。这个测试通过建立一个TCP连接,并在这个连接上发送很多请求 /应答序列。(ack包回来后向外发送一个1字节大小的包)。这个行为很像关系型数据库系统执行大量的处理,邮件服务器在一个连接里传送很多条信息。
下面的例子模拟了在30秒内持续的TCP请求/应答。
<font color=
"#000000"
>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<
/font
>
在前面的输出里,网络的处理效率达到4453psh/ack每秒,但这是在1字节的包大小下测试的。这对现实中的请求来说,不是很真实,尤其是应答的包,它们应该比1字节要大的多。
在更真实的例子里,netperf使用默认2K大小的包作请求,32K大小的包作应答。
<font color=
"#000000"
>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<
/font
>
处理效率下降非常明显,现在每秒只能处理222次。
iperf也是在两个节点之间检查连接情况,这和netperf非常类似。iperf的不同之处是它在TCP/UDP效率方面的检测更加深入,例如滑动窗口机制和QoS设置。这个工具是为想优化TCP/IP协议栈并测试协议栈效率的系统管理员设计的。
iperf工具是单个二进制文件,能运行在服务器或客户端模式。默认运行在5001端口。
启动服务(192.168.1.215):
<font color=
"#000000"
>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)
------------------------------------------------------------<
/font
>
在下面的例子中,iperf运行在客户端模式,在一个无线网络上反复测试吞吐量。这个无线网络负载很高,包括多个主机正在下载ISO镜像文件。
客户端连接到服务端(192.168.1.215)并运行一个60秒的带宽测试,5秒报告一次结果。
<font color=
"#000000"
>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
<
/font
>
在这60秒的重复测试中,吞吐量始终在4-10Mbits之间波动,看起来其它主机的流量并没有对这台机器的带宽产生太大影响。
除了TCP测试以外,iperf在UDP方面也能测试丢包和抖动。下面的iperf测试运行在同样负载的无线54Mbits G网下。就像前面例子里展示的,网络吞吐量只有最高54Mbits的里的9Mbits。
<font color=
"#000000"
># 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<
/font
>
这个例子里,有10M数据尝试传输,但是在对端实际上只收到了5.45M,包的丢失率达到了45%。
tcptrace工具提供了对指定连接的基于TCP的详细信息。工具基于libpcap文件来运行和分析指定的TCP会话。它提供的信息有时候是TCP流里很难捕捉到的。这些信息包括
tcptrace也许在一些Linux发行版的软件包仓库中已经附带了。这篇文章使用预编译的包,网址是:(http://dag.wieers.com/rpm/packages/tcptrace )。tcptrace命令从基于libpcap的文件输入。不使用任何参数的话,它列出捕捉文件里的所有唯一的连接。
下面的例子使用一个叫做bigstuff的libpcap文件。
<font color=
"#000000"
># 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<
<snip><
/font
>
1
<font
color=
"#000000"
><
/font
>
在前面的输出里,每个连接都有关联的编号,还有源主机和目的主机。tcptrace最常用的选项是 -l 和 -o ,它们提供指定连接的详细统计数据。
下面的例子列出了在bigstuff中的#1连接的所有统计数据。
<font color=
"#000000"
># 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<
/font
>
要辨别出哪个连接有足够严重的重传问题需要分析,通常这是不可能的。tcptrace工具有能力使用过滤器和判断表达式来定位有问题的连接。一个有很多人连接的饱和的网络,有可能所有的连接都在经历重传。定位哪一个连接重传最严重是关键。
在下面的例子中,tcptrace命令使用过滤器来定位重传超过100个片段的连接。
<font color=
"#000000"
># 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<<
/font
>
在前面的输出中,#16连接正经受超过100的重传,从这里开始,tcptrace只提供那个连接的统计数据。
<font color=
"#000000"
># 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:
<snip>
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<
/font
>
计算重传率:
rexmt/actual * 100 = Retransmission rate
或者
1605/18695 * 100 = 8.5%
前面的连接有8.5%的重传率,这是造成连接缓慢的原因。
tcptrace工具提供了一系列的模块来从不同维度展示数据,例如协议,端口,时间等等。这个slice模块允许你查看一段时间里的TCP性能。特别的,你能辨认出什么时候有重传发生,把它和别的性能数据结合到一起来定位瓶颈。
下面的例子展示了怎样使用tcptrace创建时间片输出。
# tcptrace -xslice bigfile
这条命令在当前目录创建了一个叫slice.dat的文件。这个特定的文件包含了间隔15秒的重传信息。
<font
color=
"#000000"
>#
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<
/font
>
为了监控网络的性能,我们需要做以下工作。
在下面的情景里,一个终端用户呼叫支持并抱怨,在web用户接口里的报告模块原本只需要15秒就能创建报告,现在却要20分钟。
系统配置
1.我们从vmstat的系统性能“仪表盘”开始。
<font color=
"#000000"
># 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<
/font
>
关键数据点:
2.使用iostat来确定是哪里创建的读请求
<font style=
"font-size:
9.8pt"
><font
color=
"#000000"
># iostat -x 1
Linux 2.4.21-40.ELsmp (mail.example.com)
03
/26/2007
avg-cpu: %user
%
nice
%sys %idle
30.00 0.00
9.33 60.67
Device:
rrqm
/s
wrqm
/s
r
/s
w
/s
rsec
/s
wsec
/s
rkB
/s
wkB
/s
avgrq-sz
avgqu-sz await svctm %util
/dev/sda
7929.01 30.34 1180.91 14.23
7929.01 357.84 3964.50 178.92 6.93
0.39 0.03 0.06 6.69
/dev/sda1
2.67
5.46 0.40 1.76 24.62
57.77 12.31 28.88 38.11
0.06 2.78 1.77 0.38
/dev/sda2
0.00
0.30 0.07 0.02 0.57
2.57 0.29 1.28
32.86 0.00 3.81 2.64
0.03
/dev/sda3
7929.01 24.58 1180.44 12.45
7929.01 297.50 3964.50 148.75 6.90
0.32 0.03 0.06 6.68
avg-cpu: %user
%
nice
%sys %idle
9.50 0.00
10.68 79.82
Device:
rrqm
/s
wrqm
/s
r
/s
w
/s
rsec
/s
wsec
/s
rkB
/s
wkB
/s
avgrq-sz
avgqu-sz await svctm %util
/dev/sda
0.00 0.00
1195.24 0.00 0.00 0.00 0.00 0.00
0.00 43.69 3.60 0.99
117.86
/dev/sda1
0.00 0.00
0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00
0.00 0.00 0.00
/dev/sda2
0.00 0.00
0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00
0.00 0.00 0.00
/dev/sda3
0.00 0.00
1195.24 0.00 0.00 0.00 0.00 0.00
0.00 43.69 3.60 0.99
117.86
avg-cpu: %user
%
nice
%sys %idle
9.23 0.00
10.55 79.22
Device:
rrqm
/s
wrqm
/s
r
/s
w
/s
rsec
/s
wsec
/s
rkB
/s
wkB
/s
avgrq-sz
avgqu-sz await svctm %util
/dev/sda
0.00 0.00
1200.37 0.00 0.00 0.00 0.00 0.00
0.00 41.65 2.12 0.99
112.51
/dev/sda1
0.00 0.00
0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00
0.00 0.00 0.00
/dev/sda2
0.00 0.00
0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00
0.00 0.00 0.00
/dev/sda3
0.00 0.00
1200.37 0.00 0.00 0.00 0.00 0.00
0.00 41.65 2.12 0.99
112.51<
/font
><
/font
>
关键数据点:
3.使用top,确定哪一个应用是系统中最活跃的。
<font
color=
"#000000"
>#
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
<
/font
>
关键数据点:
4.现在我们确定是mysql创建了这些读请求,使用strace来确定具体是什么样的读请求。
<font style=
"font-size:
9.8pt"
><font
color=
"#000000"
>#
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<
/font
><
/font
>
关键数据点:
5.使用mysqladmin命令,查看是哪个查询请求正占系统资源最大而且运行时间最长。
<font style=
"font-size:
9.8pt"
><font
color=
"#000000"
>#
.
/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
`update_datasource`=
‘Y‘
where
database_id=
‘32‘
and
update_datasource=
‘N‘
and
|
| 14 | root | localhost
| |
Query | 0
| | show
processlist<
/font
><
/font
>
关键数据点:
性能监控的数据提交给了应用程序开发者,开发分析了PHP代码,发现了代码里一个不好的实现。指定的查询假设failure数据库只伸展到10万条 记录,但实际查询的有问题的数据库却有400万条记录。结果查询不能伸展到数据库的大小。因此其它任何查询(例如创建报告)都会卡在update查询之 后。
【转载】Linux系统与性能监控,布布扣,bubuko.com
原文:http://www.cnblogs.com/yezhaohui/p/3642453.html