iostat和iowait[转]

%iowait并不能反应磁盘瓶颈

iowait实际测量的是cpu时间:
%iowait = (cpu idle time)/(all cpu time)

这个文章说明:高速cpu会造成很高的iowait值,但这并不代表磁盘是系统的瓶颈。唯一能说明磁盘是系统瓶颈的方法,就是很高的read/write时间,一般来说超过20ms,就代表了不太正常的磁盘性能。为什么是20ms呢?一般来说,一次读写就是一次寻到+一次旋转延迟+数据传输的时间。由于,现代硬盘数据传输就是几微秒或者几十微秒的事情,远远小于寻道时间2~20ms和旋转延迟4~8ms,所以只计算这两个时间就差不多了,也就是15~20ms。只要大于20ms,就必须考虑是否交给磁盘读写的次数太多,导致磁盘性能降低了。 Continue reading “iostat和iowait[转]”

Linux System and Performance Monitoring(总结篇)[转]

作者:tonnyom
原载: http://www.sanotes.net/html/y2009/393.html
版权所有。转载时必须以链接形式注明作者和原始出处及本声明。

Linux System and Performance Monitoring(总结篇)
Date: 2009.07.21
Author: Darren Hoch
译: Tonnyom[AT]hotmail.com

结束语: 这是该译文的最后一篇,在这篇中,作者提供了一个案例环境,用之前几篇所阐述的理论以及涉及到的工具,对其进行一个整体的系统性能检查.对大家更好理解系统性能监控,进行一次实战演习.
BTW:在中文技术网站上,类似内容的文章,大体是来自该作者06-07年所著论文,此译文是建立在作者为OSCON 2009重写基础上的.所以部分内容可能会存在重复雷同,特此说明下.

附录 A: 案例学习 – 性能监控之循序渐进

某一天,一个客户打电话来需要技术帮助,并抱怨平常15秒就可以打开的网页现在需要20分钟才可以打开.

具体系统配置如下:

RedHat Enterprise Linux 3 update 7
Dell 1850 Dual Core Xenon Processors, 2 GB RAM, 75GB 15K Drives
Custom LAMP software stack(译注:Llinux+apache+mysql+php 环境)

性能分析之步骤

1. 首先使用vmstat 查看大致的系统性能情况:

# 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

分析:
1,不会是内存不足导致,因为swapping 始终没变化(si 和 so).尽管空闲内存不多(free),但swpd 也没有变化.
2,CPU 方面也没有太大问题,尽管有一些运行队列(procs r),但处理器还始终有50% 多的idle(CPU id).
3,有太多的上下文切换(cs)以及disk block从RAM中被读入(bo).
4,CPU 还有平均20% 的I/O 等待情况.

结论:
从以上总结出,这是一个I/O 瓶颈.

2. 然后使用iostat 检查是谁在发出IO 请求:

# 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

分析:
1,看上去只有/dev/sda3 分区很活跃,其他分区都很空闲.
2,差不多有1200 读IOPS,磁盘本身是支持200 IOPS左右(译注:参考之前的IOPS 计算公式).
3,有超过2秒,实际上没有一个读磁盘(rkb/s).这和在vmstat 看到有大量I/O wait是有关系的.
4,大量的read IOPS(r/s)和在vmstat 中大量的上下文是匹配的.这说明很多读操作都是失败的.

结论:
从以上总结出,部分应用程序带来的读请求,已经超出了I/O 子系统可处理的范围.

3. 使用top 来查找系统最活跃的应用程序

# 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

分析:
1,占用资源最多的好像就是mysql 进程,其他都处于完全idle 状态.
2,在top(wa) 看到的数值,和在vmstat 看到的wio 数值是有关联的.

结论:
从以上总结出,似乎就只有mysql 进程在请求资源,因此可以推论它就是导致问题的关键.

4. 现在已经确定是mysql 在发出读请求,使用strace 来检查它在读请求什么.

# 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

分析:
1,大量的读操作都在不断寻道中,说明mysql 进程产生的是随机IO.
2,看上去似乎是,某一sql 查询导致读操作.

结论:
从以上总结出,所有的读IOPS 都是mysql 进程在执行某些读查询时产生的.

5. 使用mysqladmin 命令,来查找是哪个慢查询导致的.

# ./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

分析:
1,MySQL 数据库里,似乎在不断的运行table update查询.
2,基于这个update 查询,数据库是对所有的table 进行索引.

结论:
从以上总结出,MySQL里这些update 查询问题,都是在尝试对所有table 进行索引.这些产生的读请求正是导致系统性能下降的原因.

后续

把以上这些性能信息移交给了相关开发人员,用于分析他们的PHP 代码.一个开发人员对代码进行了临时性优化.某个查询如果出错了,也最多到100K记录.数据库本身考虑最多存在4百万记录.最后,这个查询不会再给数据库带来负担了.

References
• Ezlot, Phillip – Optimizing Linux Performance, Prentice Hall, Princeton NJ 2005 ISBN – 0131486829
• Johnson, Sandra K., Huizenga, Gerrit – Performance Tuning for Linux Servers, IBM Press, Upper Saddle River NJ 2005 ISBN 013144753X
• Bovet, Daniel Cesati, Marco – Understanding the Linux Kernel, O’Reilly Media, Sebastoppl CA 2006, ISBN 0596005652
• Blum, Richard – Network Performance Open Source Toolkit, Wiley, Indianapolis IN 2003, ISBN 0-471-43301-2
• Understanding Virtual Memory in RedHat 4, Neil Horman, 12/05 http://people.redhat.com/nhorman/papers/rhel4_vm.pdf
• IBM, Inside the Linux Scheduler, http://www.ibm.com/developerworks/linux/library/l-scheduler/
• Aas, Josh, Understanding the Linux 2.6.8.1 CPU Scheduler, http://josh.trancesoftware.com/linux/linux_cpu_scheduler.pdf
• Wieers, Dag, Dstat: Versatile Resource Statistics Tool, http://dag.wieers.com/home-made/dstat/

Linux System and Performance Monitoring(I/O篇)[转]

作者:tonnyom
原载: http://www.sanotes.net/html/y2009/381.html
版权所有。转载时必须以链接形式注明作者和原始出处及本声明。

Linux System and Performance Monitoring(I/O篇)
Date: 2009.07.21
Author: Darren Hoch
译: Tonnyom[AT]hotmail.com

6.0 I/O 监控介绍

磁盘I/O 子系统是Linux 系统中最慢的部分.这个主要是归于CPU到物理操作磁盘之间距离(译注:盘片旋转以及寻道).如果拿读取磁盘和内存的时间作比较就是分钟级到秒级,这就像 7天和7分钟的区别.因此本质上,Linux 内核就是要最低程度的降低I/O 数.本章将诉述内核在磁盘和内存之间处理数据的这个过程中,哪些地方会产生I/O.

6.1 读和写数据 – 内存页

Linux 内核将硬盘I/O 进行分页,多数Linux 系统的默认页大小为4K.读和写磁盘块进出到内存都为4K 页大小.你可以使用time 这个命令加-v 参数,来检查你系统中设置的页大小:

# /usr/bin/time -v date
<snip>
Page size (bytes): 4096
<snip>

6.2 Major and Minor Page Faults(译注:主要页错误和次要页错误)

Linux,类似多数的UNIX 系统,使用一个虚拟内存层来映射硬件地址空间.当一个进程被启动,内核先扫描CPU caches和物理内存.如果进程需要的数据在这2个地方都没找到,就需要从磁盘上读取,此时内核过程就是major page fault(MPF).MPF 要求磁盘子系统检索页并缓存进RAM.

一旦内存页被映射进内存的buffer cache(buff)中,内核将尝试从内存中读取或写入,此时内核过程就是minor page fault(MnPF).与在磁盘上操作相比,MnPF 通过反复使用内存中的内存页就大大的缩短了内核时间.

以下的例子,使用time 命令验证了,当进程启动后,MPF 和 MnPF 的变化情况.第一次运行进程,MPF 会更多:

# /usr/bin/time -v evolution
<snip>
Major (requiring I/O) page faults: 163
Minor (reclaiming a frame) page faults: 5918
<snip>

第二次再运行时,内核已经不需要进行MPF了,因为进程所需的数据已经在内存中:

# /usr/bin/time -v evolution
<snip>
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 5581
<snip>

6.3 The File Buffer Cache(译注:文件缓存区)

文件缓存区就是指,内核将MPF 过程最小化,MnPF 过程最大化.随着系统不断的产生I/O,buffer cache也将不断的增加.直到内存不够,以及系统需要释放老的内存页去给其他用户进程使用时,系统就会丢弃这些内存页.结果是,很多sa(译注:系统管理员)对系统中过少的free memory(译注:空闲内存)表示担心,实际上这是系统更高效的在使用caches.

以下例子,是查看/proc/meminfo 文件:

# cat /proc/meminfo
MemTotal: 2075672 kB
MemFree: 52528 kB
Buffers: 24596 kB
Cached: 1766844 kB
<snip>

可以看出,这个系统总计有2GB (Memtotal)的可用内存.当前的空闲内存为52MB (MemFree),有24 MB内存被分配磁盘写操作(Buffers),还有1.7 GB页用于读磁盘(Cached).

内核这样是通过MnPF机制,而不代表所有的页都是来自磁盘.通过以上部分,我们不可能确认系统是否处于瓶颈中.

6.4 Type of Memory Pages

在Linux 内核中,memory pages有3种,分别是:

1,Read Pages – 这些页通过MPF 从磁盘中读入,而且是只读.这些页存在于Buffer Cache中以及包括不能够修改的静态文件,二进制文件,还有库文件.当内核需要它们时,将读取到内存中.如果内存不足,内核将释放它们回空闲列表中.程序再次请求时,则通过MPF 再次读回内存.

2,Dirty Pages – 这些页是内核在内存中已经被修改过的数据页.当这些页需要同步回磁盘上,由pdflush 负责写回磁盘.如果内存不足,kswapd (与pdflush 一起)将这些页写回到磁盘上并释放更多的内存.

3,Anonymous Pages – 这些页属于某个进程,但是没有任何磁盘文件和它们有关.他们不能和同步回磁盘.如果内存不足,kswapd 将他们写入swap 分区上并释放更多的内存("swapping" pages).

6.5 Writing Data Pages Back to Disk

应用程序有很多选择可以写脏页回磁盘上,可通过I/O 调度器使用 fsync() 或 sync() 这样的系统函数来实现立即写回.如果应用程序没有调用以上函数,pdflush 进程会定期与磁盘进行同步.

# ps -ef | grep pdflush
root 186 6 0 18:04 ? 00:00:00 [pdflush]

7.0 监控 I/O

当觉得系统中出现了I/O 瓶颈时,可以使用标准的监控软件来查找原因.这些工具包括了top,vmstat,iostat,sar.它们的输出结果一小部分是很相似,不过每个也都提供了各自对于性能不同方面的解释.以下章节就将讨论哪些情况会导致I/O 瓶颈的出现.

7.1 Calculating IO’s Per Second(译注:IOPS 的计算)

每个I/O 请求到磁盘都需要若干时间.主要是因为磁盘的盘边必须旋转,机头必须寻道.磁盘的旋转常常被称为"rotational delay"(RD),机头的移动称为"disk seek"(DS).一个I/O 请求所需的时间计算就是DS加上RD.磁盘的RD 基于设备自身RPM 单位值(译注:RPM 是Revolutions Perminute的缩写,是转/每分钟,代表了硬盘的转速).一个RD 就是一个盘片旋转的

半圆.如何计算一个10K RPM设备的RD 值呢:

1, 10000 RPM / 60 seconds (10000/60 = 166 RPS)
2, 转换为 166分之1 的值(1/166 = 0.006 seconds/Rotation)
3, 单位转换为毫秒(6 MS/Rotation)
4, 旋转半圆的时间(6/2 = 3MS) 也就是 RD
5, 加上平均3 MS 的寻道时间 (3MS + 3MS = 6MS)
6, 加上2MS 的延迟(6MS + 2MS = 8MS)
7, 1000 MS / 8 MS (1000/8 = 125 IOPS)

每次应用程序产生一个I/O,在10K RPM磁盘上都要花费平均 8MS.在这个固定时间里,磁盘将尽可能且有效率在进行读写磁盘.IOPS 可以计算出大致的I/O 请求数,10K RPM 磁盘有能力提供120-150 次IOPS.评估IOPS 的效能,可用每秒读写I/O 字节数除以每秒读写IOPS 数得出.

7.2 Random vs Sequential I/O(译注:随机/顺序 I/O)

per I/O产生的KB 字节数是与系统本身workload相关的,有2种不同workload的类型,它们是sequential和random.

7.2.1 Sequential I/O(译注:顺序IO)

iostat 命令提供信息包括IOPS 和每个I/O 数据处理的总额.可使用iostat -x 查看.顺序的workload是同时读顺序请求大量的数据.这包括的应用,比如有商业数据库(database)在执行大量的查询和流媒体服务.在这个 workload 中,KB per I/O 的比率应该是很高的.Sequential workload 是可以同时很快的移动大量数据.如果每个I/O 都节省了时间,那就意味了能带来更多的数据处理.

# 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 1 06080.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 594.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

评估IOPS 的效能,可用每秒读写I/O 字节数除以每秒读写IOPS 数得出,比如
rkB/s 除以 r/s
wkB/s 除以 w/s

53040/105 = 505KB per I/O
71152/102 = 697KB per I/O
在上面例子可看出,每次循环下,/dev/sda 的per I/O 都在增加.

7.2.2 Random I/O(译注:随机IO)

Random的worklaod环境下,不依赖于数据大小的多少,更多依赖的是磁盘的IOPS 数.Web和Mail 服务就是典型的Random workload.I/O 请求内容都很小.Random workload是同时每秒会有更多的请求数产生.所以,磁盘的IOPS 数是关键.

# iostat -x 1

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.57 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

计算方式和之前的公式一致:

2640/102 = 23KB per I/O
3176/130 = 24KB per I/O

(译注:对于顺序I/O来说,主要是考虑读取大量数据的能力即KB per request.对于随机I/O系统,更需要考虑的是IOPS值)

7.3 When Virtual Memory Kills I/O

如果系统没有足够的RAM 响应所有的请求,就会使用到SWAP device.就像使用文件系统I/O,使用SWAP device 代价也很大.如果系统已经没有物理内存可用,那就都在SWAP disk上创建很多很多的内存分页,如果同一文件系统的数据都在尝试访问SWAP device,那系统将遇到I/O 瓶颈.最终导致系统性能的全面崩溃.如果内存页不能够及时读或写磁盘,它们就一直保留在RAM中.如果保留时间太久,内核又必须释放内存空间.问题来了,I/O 操作都被阻塞住了,什么都没做就被结束了,不可避免地就出现kernel panic和system crash.

下面的vmstat 示范了一个内存不足情况下的系统:

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

这个结果可看出,大量的读请求回内存(bi),导致了空闲内存在不断的减少(free).这就使得系统写入swap device的块数目(so)和swap 空间(swpd)在不断增加.同时看到CPU WIO time(wa)百分比很大.这表明I/O 请求已经导致CPU 开始效率低下.

要看swaping 对磁盘的影响,可使用iostat 检查swap 分区

# 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

在这个例子中,swap device(/dev/sda1) 和 file system device(/dev/sda3)在互相作用于I/O. 其中任一个会有很高写请求(w/s),也会有很高wait time(await),或者较低的服务时间比率(svctm).这表明2个分区之间互有联系,互有影响.

7.4 结论

I/O 性能监控包含了以下几点:

1,当CPU 有等待I/O 情况时,那说明磁盘处于超负荷状态.
2,计算你的磁盘能够承受多大的IOPS 数.
3,确定你的应用是属于随机或者顺序读取磁盘.
4,监控磁盘慢需要比较wait time(await) 和 service time(svctm).
5,监控swap 和系统分区,要确保virtual memory不是文件系统I/O 的瓶颈.

nagios监控iostat[技术]

网上NetSeek写了一篇文章就是用nagios监控iostat的,但他使用的都是源码包编译的,具体可以参考他的这篇文章http://bbs.linuxtone.org/thread-2289-1-1.html

但编译的方式对于多机部署上来讲可能会有些不太方便,所以蚊子我在网上查了一下要想让nagios监控iostat需要的rpm包

蚊子我的环境都是centos5,所以我下载的包都是rhel5的,有需要其他环境的,我会在下面把下载地址给出,各位自己去找适合自己的。

http://packages.sw.be/perl-Nagios-Plugin/perl-Nagios-Plugin-0.33-1.el5.rf.noarch.rpm
http://dag.wieers.com/rpm/packages/perl-Class-Accessor/perl-Class-Accessor-0.31-1.el5.rf.noarch.rpm
http://dag.wieers.com/rpm/packages/perl-Config-Tiny/perl-Config-Tiny-2.12-1.el5.rf.noarch.rpm
http://dag.wieers.com/rpm/packages/perl-Math-Calc-Units/perl-Math-Calc-Units-1.06-1.el5.rf.noarch.rpm
http://dag.wieers.com/rpm/packages/perl-Params-Validate/perl-Params-Validate-0.89-1.el5.rf.i386.rpm(32位版)
http://dag.wieers.com/rpm/packages/perl-Params-Validate/perl-Params-Validate-0.89-1.el5.rf.x86_64.rpm(64位版)
http://dag.wieers.com/rpm/packages/perl-Regexp-Common/perl-Regexp-Common-2.120-1.2.el5.rf.noarch.rpm

如果需要其他环境的包可以到以下地址下载

perl-nagios-plugin                    http://packages.sw.be/perl-Nagios-Plugin/
perl-class-accessor                 http://dag.wieers.com/rpm/packages/perl-Class-Accessor/
perl-config-tiny                           http://dag.wieers.com/rpm/packages/perl-Config-Tiny/
perl-math-calc-units                 http://dag.wieers.com/rpm/packages/perl-Math-Calc-Units/
perl-params-validate                http://dag.wieers.com/rpm/packages/perl-Params-Validate/
perl-regexp-common                http://dag.wieers.com/rpm/packages/perl-Regexp-Common/

接下来出场的就是我们的主角,监控脚本check_iostat,下载地址是

http://www.ofn.dk/files/software/check_iostat

将此文件下载到/path/to/nagios/libexec下,并赋予执行权限,然后可以通过执行此脚本查看返回值

# ./check_iostat
IOSTAT OK – user 0.50 nice 0.01 sys 1.47 iowait 2.09 idle 0.00  | iowait=2.09%;; idle=0.00%;; user=0.50%;; nice=0.01%;; sys=1.47%;;

当然iostat命令是需要的,如果执行中出现以下错误

# ./check_iostat
Can’t exec “iostat”: No such file or directory at ./check_iostat line 69.
IOSTAT UNKNOWN – Error executing iostat command

请查看sysstat包是否安装

对于批量安装我的想法是,首先将check_iostat和所有rpm包打包上传到所有的服务器,这里最好的选择是rsync的方式,如果都是32位或都是64位的系统,可以直接执行rpm –ivh perl-*就行了,如果是两者都有,我这里写了一个脚本用来判断操作系统,脚本如下

#!/bin/bash
banner=$(uname -i)
cd ~/src
rpm -ivh perl-Class-Accessor-0.31-1.el5.rf.noarch.rpm
rpm -ivh perl-Config-Tiny-2.12-1.el5.rf.noarch.rpm
rpm -ivh perl-Math-Calc-Units-1.06-1.el5.rf.noarch.rpm
rpm -ivh perl-Regexp-Common-2.120-1.2.el5.rf.noarch.rpm
case $banner in
i386)
rpm -ivh perl-Params-Validate-0.89-1.el5.rf.i386.rpm
;;
x86_64)
rpm -ivh perl-Params-Validate-0.89-1.el5.rf.x86_64.rpm
;;
*)
exit 1
;;
esac

rpm -ivh perl-Nagios-Plugin-0.33-1.el5.rf.noarch.rpm

这里把所有包,包含32位和64位的同时放到src目录下。