应用系统的大部分瓶颈在IO上、不是所有的问题都可以利用内存或者CPU Cache做缓存解决、Mysql单表几千万的数据、早已不是罕见现象了、意味着, 使用内存当缓存、存储空间是不够用的. 大部分请求还是会打到硬盘上.
IO性能、顺序和随机访问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 从硬盘厂商的性能报告上、通常可以看到两个指标: 响应时间(Response Time)和数据传输率(Data Transfer Rate)
现在常用的硬盘有两种: HDD硬盘(机械硬盘) 和 SSD硬盘(固态硬盘). 现在的HDD硬盘使用的是 SATA 3.0 的接口. SSD硬盘有两种接口: SATA 3.0 和 PCI Express 接口
SATA 3.0 接口、带宽是6Gb/s, b是bit、相当于每秒传输 768M 数据; 日常使用的HDD硬盘的数据传输率差不多200MB/s SSD的硬盘、数据传输率差不多500MB/s, 实际SSD的硬盘可以更快. 可以换用PCI Experss的三星SSD硬盘、 它的数据传输率、在读取的时候可以达到2GB/s 左右、差不多是HDD硬盘的10倍、写入时也有1.2GB/s.
除了数据传输率、我们还关心响应时间. SSD硬盘大概在几十微秒、HDD大概在几ms到十几ms、差异在几十倍甚至上百倍.
单看响应时间和吞吐率、硬盘性能还可以、基本上在ms时间内可以返回, 1s内可传输的数据也有200MB左右、 db一条记录、一般也就1kb大小、差不多每秒可写入 200M*1024 / 1 约20w条数据、似乎和平时经验不符 ?
因为硬盘顺序读写和随机读写的性能差异很大. SSD随机读写的时候、数据传输率只有40MB/s、只有顺序读写情况的几十分之一、按照每次读取4KB计算、 40MB/s / 4kb = 10000次、即: 每秒随机读取1万次、写入会多一些、1s大概90MB、即: 2w多次 这个每秒读写的次数、称为IOPS、即: 每秒输入输出操作的次数
|
HDD的IOPS通常只有100左右、而不是20w次、这个100怎么得到的呢 ?如何优化 ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| 一块机械硬盘由盘面、磁头和悬臂三个部件组成. 盘面: 就是实际存储数据的盘片、通常是使用铝、玻璃或者陶瓷制成的光滑盘片, 盘面有一层磁性涂层 数据就存储在磁性的涂层上、中间有一个受电机控制的转轴, 用来控制盘面旋转.
硬盘一个很重要的指标是转速, 通常有5400转、7200转、10000转的、这个转速指的就是转轴的旋转速度、 英文单位 RPM, 即: 每分钟的旋转圈数、7200转为例, 折算到s、就是120圈
磁头: 数据是通过磁头从盘面读取、然后通过电力信号传输给控制电路、接口、再到总线的 通常一个盘面在正反两面有连你刚刚磁头、且: 一块硬盘也不是只有一个盘面、而是上下堆叠了很多个盘面、 各个盘面是平行的、每个盘的正反两面都有磁头.
悬臂: 连接在磁头上、在一定范围内把磁头定位到某个特定的磁道上.
盘面通常是圆形的、多个同心圆组成、每个磁道有自己的编号, 悬臂用来控制读哪个磁道的数据 磁道会分成一个个扇区、上下平响的一个个盘面的相同扇区叫一个柱面、
读取数据分两步: 1. 将盘面旋转到某一个位置、在这个位置上、悬臂可以定位到整个盘面的任意子区间、这个区间称为`几何扇区` 2. 将悬臂移动到特定磁道的特定扇区、找到之后磁头落下、读取数据 所以, 需要的时间也由两个部分构成: 1. 平均延时, 就是将几何扇区对准悬臂的时间 7200转为例, 1s可以旋转240个半圈、即: 1s/240 = 4/71ms 2. 平均询道时间, 即 悬臂定位到扇区的时间 HDD硬盘一般在4-10ms、 这样随机数据访问延时一般在8-14ms, 那么 1s/8ms = 125 IOPS 或者 1s/14ms = 70 IOPS
|
如何定位 IO_WAIT
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 由上边可以看到、即使是PCI Express接口的SSD硬盘、IOPS也只有2w左右, CPU 的主频通常在2GHZ以上、 也就是每秒可以做20亿次操作. 即使一条指令需要多个时钟周期、一秒内CPU可执行的指令数和硬盘能进行的操作次数 也有好几个数量级的差异, 所以常听到性能瓶颈在IO上的说法、因为CPU发出指令之后、需要等待IO操作完成.
如何判断程序性能问题是否真的来源于IO瓶颈呢 ? 1. top指令 top指令的输出结果中、有一行 %CPU 开头、有一个 wa 的指标、就代表iowait, 即: CPU等待io操作完成花费的时间占CPU的百分比
iostat可以看到实际的情况
avg-cpu: %user %nice %system %iowait %steal %idle 17.02 0.01 2.18 0.04 0.00 80.76 Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn sda 1.81 2.02 30.87 706768 10777408
tps: 对应的就是硬盘的 IOPS 指标 KB_read/s 和 kb_write/s 对应的就是 数据传输指标 iotop 可以看到具体哪一个进程占用了大量的io
|