Linux调优-I/O
分类: Linux1428人阅读评论(0)收藏举报

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 参数,来检查你系统中设置的页大小:


[
root@monitor ~]# /usr/bin/time -v date
Fri Sep 2516:46:35 CST 2009
Command being timed: "date"
User time(seconds): 0.00
System time(seconds): 0.00
Percent of CPU this job got: ?%
Elapsed (wall clock)time(h:mm:ss or m:ss): 0:00.00
Average shared text size(kbytes): 0
Average unshared data size(kbytes): 0
Average stack size(kbytes): 0
Average total size(kbytes): 0
Maximum resident setsize(kbytes): 0
Average resident setsize(kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 183
Voluntary context switches: 1
Involuntary context switches: 1
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size(bytes): 4096
Exit status: 0

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
Major (requiring I/O) page faults: 163
Minor (reclaiming a frame) page faults: 5918

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

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

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

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

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

[root@opt-001 ~]# cat /proc/meminfo
MemTotal:      4042656 kB
MemFree:         97600 kB
Buffers:        345260 kB
Cached:        2874712 kB
SwapCached:          0 kB
Active:        2494768 kB
Inactive:      1134932 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:      4042656 kB
LowFree:         97600 kB
SwapTotal:     8193140 kB
SwapFree:      8193040 kB
Dirty:            1252 kB
Writeback:           0 kB
AnonPages:      409484 kB
Mapped:        1253336 kB
Slab:           221056 kB
PageTables:      20172 kB
NFS_Unstable:        0 kB
Bounce:              0 kB
CommitLimit:  10214468 kB
Committed_AS:  2218724 kB
VmallocTotal: 34359738367 kB
VmallocUsed:    267224 kB
VmallocChunk: 34359469767 kB
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
Hugepagesize:     2048 kB

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

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

6.4 Type of Memory Pages

Linux 内核中,memory pages3,分别是:

1,Read Pages - 这些页通过MPF 从磁盘中读入,而且是只读.这些页存在于BufferCache中以及包括不能够修改的静态文件,二进制文件,还有库文件.当内核需要它们时,将读取到内存中.如果内存不足,内核将释放它们回空闲列表中.程序再次请求时,则通过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),机头的移动称为”diskseek”(DS).一个I/O 请求所需的时间计算就是DS加上RD.磁盘的RD 基于设备自身RPM 单位值(译注:RPM Revolutions Perminute的缩写,是转/每分钟,代表了硬盘的转速).一个RD 就是一个盘片旋转的半圆.如何计算一个10K RPM设备的RD 值呢:

1, 10000 RPM / 60 seconds (10000/60 = 166RPS)
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的类型,它们是sequentialrandom.

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

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


[
root@opt-001 mysql_db]# iostat -x 1
Linux 2.6.18-164.el5 (opt-001.jobkoo.com)       09/27/2009

avg-cpu:  %user   %nice%system %iowait  %steal   %idle
0.690.021.010.150.0098.13

Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.1536.280.7512.1127.35387.6232.250.3124.330.540.69
sda1              0.000.000.000.000.000.009.990.005.294.430.00
sda2              0.1017.080.406.5610.18189.1628.650.079.960.470.33
sda3              0.000.000.000.000.000.0046.300.0020.8720.600.00
sda4              0.000.000.000.000.000.002.000.0017.2017.200.00
sda5              0.0419.210.365.5517.16198.4636.490.2441.250.740.44

avg-cpu:  %user   %nice%system %iowait  %steal   %idle
0.000.000.000.250.0099.75

Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.0060.000.00114.000.001392.0012.210.443.850.161.80
sda1              0.000.000.000.000.000.000.000.000.000.000.00
sda2              0.0036.000.0083.000.00952.0011.470.384.610.161.30
sda3              0.000.000.000.000.000.000.000.000.000.000.00
sda4              0.000.000.000.000.000.000.000.000.000.000.00
sda5              0.0024.000.0031.000.00440.0014.190.061.810.160.50

avg-cpu:  %user   %nice%system %iowait  %steal   %idle
0.000.000.000.000.00100.00

Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.000.000.000.000.000.000.000.000.000.000.00
sda1              0.000.000.000.000.000.000.000.000.000.000.00
sda2              0.000.000.000.000.000.000.000.000.000.000.00
sda3              0.000.000.000.000.000.000.000.000.000.000.00
sda4              0.000.000.000.000.000.000.000.000.000.000.00
sda5              0.000.000.000.000.000.000.000.000.000.000.00

评估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)

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


# iostat -x 1


avg-cpu: %user %nice%sys %idle
2.040.0097.960.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.00633.673.06102.3124.495281.6312.242640.82288.8973.67113.8927.2250.00
/dev/sda1 0.005.100.002.040.0057.140.0028.5728.001.1255.0055.0011.22
/dev/sda2 0.00628.573.06100.2724.495224.4912.242612.24321.5072.55121.2530.6350.00
/dev/sda3 0.000.000.000.000.000.000.000.000.000.000.000.000.00

avg-cpu: %user %nice%sys %idle
2.150.0097.850.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.0041.946.45130.9851.61352.6925.813176.3419.792.90286.327.3715.05
/dev/sda1 0.000.000.000.000.000.000.000.000.000.000.000.000.00
/dev/sda2 0.0041.944.30130.9834.41352.6917.203176.3421.182.90320.008.2415.05
/dev/sda3 0.000.002.150.0017.200.008.600.008.000.000.000.000.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 panicsystem 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 458201488472    30 132   992    0 2437 765723 50  0 23
11  0     1376  3256 458201488888    57 245   416    0 2391 717310 90  0 0
12  0     1582  1688 458281490228    63 131  1348   76 2432 7315 1090  0 10
12  2     3981  1848 45468 1489824  185 56   2300   68 2478 9149 15 12  0 73
14  2     10385 2400 444841489732     0 87   1112   20 2515 116200 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 分区

首先利用fdisk -l查看一下系统swap是哪个分区

[root@monitor ~]# fdisk -l

Disk /dev/sda: 320.0 GB, 320072933376 bytes
255 heads, 63 sectors/track, 38913 cylinders
Units = cylinders of 16065*512 = 8225280 bytes

Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *12520078183  Linux
/dev/sda2              2652474194571583  Linux
/dev/sda3            52485769419296582  Linux swap / Solaris
/dev/sda4            5770389132662291805  Extended
/dev/sda5            577038913266229148+  83  Linux

# iostat -x 1 sda3

avg-cpu: %user %nice%sys %idle
0.000.00100.000.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.001766.674866.671700.0038933.3331200.0019466.6715600.0010.686526.67100.565.083333.33
/dev/sda1 0.00833.3333.331700.00266.6722933.33133.3311466.6713.386133.33358.4611.351966.67
/dev/sda2 0.000.004833.330.0038666.67533.3319333.33266.678.11373.338.076.9087.00
/dev/sda3 0.00933.330.000.000.007733.330.003866.670.0020.002145.077.37200.00

在这个例子中,swap device(/dev/sda3) 和 file system device(/dev/sda1)在互相作用于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 的瓶颈.