磁盘I/O是任何Linux系统中最低速的部分。这主要是由于它与CPU的距离较远,还有就是磁盘需要机械地运动才能工作(就是磁盘通过转动然后寻找文件位置)。以下描述了几种内核获取I/O数据的方式,从磁盘到内存,或者从内存到磁盘。
以内存页的形式读写数据:Linux内核将磁盘分割成页式结构,许多Linux系统默认页的大小为4K。内存读写磁盘以4K页面大小进行。输入下面命令查看(注意这里不能直接使用time):
/usr/bin/time -v date
运行上面的命令后,会有一个Page size(bytes):4096.
Page size (bytes): 4096
主要与次要页面错误(MPF与MnPF):Linux使用一个虚拟内存层映射到物理地址空间。这种映射是按需进行的,当一个进程开始,内核仅映射它所需要的。当一个程序开始运行,内核首先搜索CPU缓存然后是物理内存,如果数据在任意其中一个中都不存在,内核将会声明一个主要页面错误(MPF)。MPF就是到磁盘子系统中检索页面然后把它们缓存到RAM里面。
一旦内存页面映射到缓存区,内核利用这些页面生成一个次要页面错误(MnPF)。MnPF保存系统时间通过重用内存中的一个页面,而不是将它放回磁盘。以下的例子中将会展示一个应用程序启动的时候有多少个MPF和MnPF,一般首次启动,MPF多一些:
/usr/bin/time -v evolution结果:
Major (requiring I/O) page faults: 163第二次运行结果:
Minor (reclaiming a frame) page faults: 5918
Major (requiring I/O) page faults: 0文件 缓冲区高速缓存(FIle Buffer Cache):内核使用这个用来减少MPFs,增大MnPFs。由于随着时间的推移,系统产生大量的I/O。缓存区高速缓存也将会继续增长,直到内存不足,内核需要释放出来一些页面用于其他用处的时候,操作系统将会离开这些内存中的页面。最终的结果是许多系统管理员看到少量的空闲内存进而担心,实际中,操作系统只是很好使用它的高速缓存。可通过查看/proc/meminfo查看。
Minor (reclaiming a frame) page faults: 5581
# cat /proc/meminfo可以看到此系统2G内存,52MB内存空闲,24MB分配给磁盘写操作(Buffers )。从磁盘读取的1.7GB的页面在内存中(就是缓存Cached)。
MemTotal: 2075672 kB
MemFree: 52528 kB
Buffers: 24596 kB
Cached: 1766844 kB
内核通过MnPF机制使用这些,而不是把所有的页面从磁盘中拷贝出来。从这些统计的数据中判决操作系统是否过载是不可能的,我们只是看了其中的一部分数据。
Linux内核中的内存页面种类一般有三种,如下:
可读页面:这些页面的数据通过硬盘读入,并且是只读的且是硬盘支持的。这些页面存在于缓存区高速缓存内,包含有永不修改的静态文件、二进制文件和库文件。当内核需要这些文件的时候,内核将他们拷贝到内存。如果可用的内存空间过小,内核将会“偷”出来这些页面,然后把它们放到空闲的列表中,引起一个程序必须执行MPF然后将它们拷贝回来。
脏页面:这些页面的数据在内存中已经被内核修改,所以这些页面需要使用pdflush进程同步回磁盘。在可使用内存很少的情况下,kswapd配合pdflush将这些页面写入到磁盘确保内存中有足够的空间。
匿名页面:这些页面的数据属于一个进程,但是没有任何的文件或者后备存储器与它们相关。它们不能同步回磁盘。在内存紧张的情况下,kswapd将这些数据写入到swap分区作为临时存储,当RAM足够用的时候再读取回来。
页面数据写入到磁盘:
通过调用fsync()或者sync()系统调用,应用程序本身可能立刻会选择写脏页面到磁盘。这些系统调用声明一个直接的请求到I/O调度器。如果一个应用程序没有调用这些系统调用,那么pdflush内核进程每隔一段时间运行,晶这些页面数据写入磁盘。
我们说到底还是要对Linux系统 的I/O状态进行监控,找出系统I/O的瓶颈。监控I/O可使用的工具有top、vmstat、iostat、sar。这些输出很相似,但是每一个工具又关注的是不同的方面,主要显示出这方面的性能。引起I/O瓶颈的条件有以下几种:
1、计算每秒的I/O
每一个I到磁盘的/O请求都占用这一段确定的时间,主要是由于磁盘必须旋转着以寻找到磁头。磁盘的旋转经常涉及到“旋转延时(RD)”,磁头的移动称为“磁盘定位(DS)”。磁盘的RD是以设备的RPM(ps:一分钟多少转)为基础的,RD是绕着磁盘半转的,为了说清楚这个问题,下面举个例子。
怎么计算10K RPM的设备的RD?
一秒钟转的圈:10000/60=166RPS,所以转一圈所花费的时间就是1/166=0.006s,也就是说转一圈花费0.006*1000毫秒=6ms。按照定义RD=6ms/2=3ms。在与平均的查找时间3ms相加,再加上2ms的内部传输延时,则一秒钟可处理的I/O数量为1000/(3+3+2)=125IOPS。
所以可以看出一个10K RPM的磁盘,当一个应用程序发起一个I/O请求时候,需要花费平均8ms的时间去服务于那和I/O。I/O请求的数量通常是由IOPS来衡量。10K RPM的磁盘一般有120到150的IOPS。测试有效的IOPS时候,可以用IOPS的总量除以读入或者写入数据的I/O的数量。
2、随机I/O与连续I/O
每秒I/O多少KB和系统的工作负载相关。Linux系统有两种不同的工作负载,分别是连续的和随机的。
首先看下顺序I/O,通过iostat命令可以查看IOPS和处理数据时候I/O的数量。顺序工作负载需要一次顺序读取大量的数据,这种应用程序如企业级数据库,需要执行大量的查询和获取流媒体服务数据。在连续工作负载下,每个I/O通道KB的速度是高速率。连续工作负载的性能依赖于移动大量的数据尽可能地快。如果每个I/O都耗费时间,要可能多的获取那个I/O上的数据。可以通过使用下面的命令来查看I/O的情况:
# iostat -x 1
avg-cpu: %user %nice %sys %idle0.00 0.00 57.1 4 42.86Device: 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从上面可以看出有效I/O的速率是用(rkB/s)除以(r/s)或者是用(wkB/s)除以(w/s)。所以磁盘sda的速率是53040/105=505kB per I/O。
下面介绍随机I/O,随机I/O工作负载不是根据数据的大小,依据一个磁盘中可用的IOPS的数量。Web和邮件服务器是随机获取工作负载的。I/O请求是很少的。随机工作负载依赖于一次可以处理多少请求。因此,磁盘可用IOPS的数量是至关重要的。
avg-cpu: %user %nice %sys %idle在随机工作负载情况下,磁盘的速率是2640/102=23kB per I/O。
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
操作系统没有足够的内存适应所有的I/O请求,就要开始使用swap分区。和文件系统I/O一致,写入swap分区相当耗时。如果操作系统的RAM被耗尽,那么需要在swap分区内大量创建页表。如果交换分区和数据试图访问位置在同一个文件系统上,那么操作系统将进入争夺I/O路径的状态。这将引起系统性能完全降低。如果一个页面既不能读或者不能写回磁盘,它们将永远停留在RAM里面。如果这些数据停留地太久,内核需要将需要释放一些RAM。现在的问题是I/O通道阻塞,无法进行任何操作。这将不可避免地导致内核崩溃,然后系统挂掉!
I/O性能总结:
1、任何时候CPU是等待I/O的状态,那么磁盘是超载的。
2、计算出磁盘可维持的IOPS的数目。
3、检测程序需要随机磁盘接入还是连续磁盘接入。
4、通过比较等待时间和服务时间来监控低速磁盘。
5、监控交换分区和文件系统以保证swap分区没有争夺文件系统I/O。