磁盘性能
磁盘IO
磁盘是距离cpu最远的地方,最容易成为系统的性能瓶颈,我们知道数据必须加载到内存才可以被CPU使用,要了解磁盘IO,必须得了解操作系统是如何处理内存和硬盘的IO
缺页中断
内存和硬盘的IO单位是页,在linux中一页的大小是4kb,查看默认的页大小
/usr/bin/time -v date
page size: 4096
在程序运行的时候,由于程序太大,不会把所有的数据都映射到内存中,而是通过通过内存和硬盘之间的不断交换来读取相应的数据,查找过程是:当程序开始运行的时候,内核首先去查找内存缓存和物理内存,如果数据已经在内存中,则忽略,如果数据不在内存里就引起一个缺页中断(Page Fault) 然后从硬盘读取缺页,并把缺页缓存到物理内存里。
缺页中断可分为主缺页中断(Major Page Fault)和次缺页中断(Minor Page Fault),要从磁盘读取数据而产生的中断是主缺页中断;数据已经被读入内存并被缓存起来,从内存缓存区中而不是直接从硬盘中读取数据而产生的中断是次缺页中断
上面的内存缓存区起到了预读硬盘的作用,内核先在物理内存里寻找缺页,没有的话产生次缺页中断从内存缓存里找,如果还没有发现的话就从硬盘读取。很显然,把多余的内存拿出来做成内存缓存区提高了访问速度,这里还有一个命中率的问题,运气好的话如果每次缺页都能从内存缓存区读取的话将会极大提高性能。要提高命中率的一个简单方法就是增大内存缓存区面积,缓存区越大预存的页面就越多,命中率也会越高。下面的 time 命令可以用来查看某程序第一次启动的时候产生了多少主缺页中断和次缺页中
内存缓存区
从上面的内存缓存区(也叫文件缓存区 File Buffer Cache)数据肯定快于硬盘,我们运行 Linux 一段时间后会发现虽然系统上运行的程序不多,但是可用内存总是很少,这样给大家造成了 Linux 对内存管理很低效的假象,事实上 Linux 把那些暂时不用的物理内存高效的利用起来做预存(内存缓存区)呢
$ cat /proc/meminfo
MemTotal: 8182776 kB
MemFree: 3053808 kB
Buffers: 342704 kB
Cached: 3972748 kB
这台服务器总共有 8GB 物理内存(MemTotal),3GB 左右可用内存(MemFree),343MB 左右用来做磁盘缓存(Buffers),4GB 左右用来做文件缓存区(Cached),可见 Linux 真的用了很多物理内存做 Cache,而且这个缓存区还可以不断增长。
那么,程序中那些数据需要优先加载到内存中呢,这是程序语言决定的
顺序 IO 和 随机 IO
IO 可分为顺序 IO 和 随机 IO 两种,性能监测前需要弄清楚系统偏向顺序 IO 的应用还是随机 IO 应用。顺序 IO 是指同时顺序请求大量数据,比如数据库执行大量的查询、流媒体服务等,顺序 IO可以同时很快的移动大量数据。可以这样来评估 IOPS 的性能
rio/s = (一秒钟读取总KB)/ (一秒钟读取次数) = (rkB/s) / (r/s)
wio/s = (一秒钟写入总KB)/ (一秒钟写入次数) = (wkB/s) / (w/s)
顺序IO应该注重IO的吞吐能力(KB/s)
$ 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
第一秒:45060.00 / 99.00 = 455.15 KB per IO
第二秒:54272.00 / 112.00 = 484.57 KB per IO
说明磁盘IO是稳定的
随机IO侧重于访问次数,Web 服务、Mail 服务等每次请求的数据都很小,随机 IO 每秒同时会有更多的请求数产生,所以磁盘的每秒能 IO 多少次是关键
SWAP
$ cat /proc/meminfo
MemTotal: 8182776 kB
MemFree: 2125476 kB
Buffers: 347952 kB
Cached: 4892024 kB
SwapCached: 112 kB
...
SwapTotal: 4096564 kB
SwapFree: 4096424 kB
...
$ 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
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