前言
大家好,我是jiantaoyab,在开发应用系统的时候,遇到的性能瓶颈大部分都在 I/O 上。这是我作为学习笔记的23篇,本篇文章大家我们就来看看硬盘 I/O 性能。
IO性能
硬盘性能报告,通常有两个指标。一个是响应时间(Response Time),另一个叫作数据传输率(Data Transfer Rate)。
数据传输率
我们现在常用的硬盘有两种。一种是 HDD 硬盘,也就是机械硬盘。
另一种是 SSD 硬盘,一般也叫作固态硬盘。 HDD 硬盘,用的是 SATA 3.0 的接口。 SSD 硬盘通常会用两种接口,一部分用的也是 SATA 3.0 的接口;另一部分呢,用的是 PCI Express 的接口。
现在常用的 SATA 3.0 的接口,带宽是 6Gb/s。这里的“b”是比特。
这个带宽相当于每秒可以传输 768MB 的数据。而我们日常用的 HDD 硬盘的数据传输率,差不多在 200MB/s 左右。
响应时间
这个指标,是程序发起一个硬盘的写入请求,直到这个请求返回的时间。光看响应时间和数据传输率这两个指标,似乎我们的硬盘性能很不错。即使是廉价的 HDD 硬盘,接收一个来自 CPU 的请求,也能够在几毫秒时间返回。一秒钟能够传输的数据,也有 200MB 左右。
我们平时往数据库里写入一条记录,也就是 1KB 左右的大小。我们拿 200MB 去除以 1KB,那差不多每秒钟可以插入 20 万条数据。但是这个计算出来的数字,似乎和我们日常的经验不符合啊?这又是为什么呢?
答案就来自于硬盘的读写。在顺序读写和随机读写的情况下,硬盘的性能是完全不同的。

图片中有一个“4K”的指标。它其实是程序去随机读取磁盘上某一个 4KB 大小的数据,一秒之内可以读取到多少数据。
假如数据传输率有 40MB/s ,一次读取 4KB 的数据
40MB/4KB=10,000
40MB / 4KB = 10,000
40MB/4KB=10,000
一秒之内,这块 SSD 硬盘可以随机读取 1 万次的 4KB 的数据。
如果是写入的话呢,会更多一些,90MB /4KB 差不多是 2 万多次。
这个每秒读写的次数,称之为IOPS,也就是每秒输入输出操作的次数。比起响应时间,我们更关注 IOPS 这个性能指标。
IOPS 和 DTR(Data Transfer Rate,数据传输率)才是输入输出性能的核心指标。
这是因为,在实际的应用开发当中,对于数据的访问,更多的是随机读写,而不是顺序读写。服务器承受的“并发”,其实是在说,会有很多个不同的进程和请求来访问服务器。自然,它们在硬盘上访问的数据,是很难顺序放在一起的。这种情况下,随机读写的 IOPS 才是服务器性能的核心指标。
服务器整体负载
在 Linux 下,我们可以通过 top 这样的命令,来看整个服务器的整体负载。在应用响应慢的时候,我们可以先通过这个指令,来看 CPU 是否在等待 I/O 完成自己的操作。进一步地,我们可以通过 iostat 这个命令,来看到各个硬盘这个时候的读写情况。而 iotop 这个命令,能够帮助我们定位到到底是哪一个进程在进行大量的 I/O 操作。
执行下面的操作先看看自己有没有安装这些包
sudo yum install stress
sudo yum install sysstat
Linux下输入iostat看到实际的硬盘读写情况。

启动压力测试,让 stress 这个程序模拟两个进程不停地从内存里往硬盘上写数据。
在 top 的输出里面,CPU 就有大量的 sy 和 wa,也就是系统调用和 iowait。

机械硬盘
拆解机械硬盘

一块机械硬盘是由盘面、磁头和悬臂三个部件组成的。
盘面(Disk Platter)。盘面是实际存储数据的盘片。盘面本身通常是用的铝、玻璃或者陶瓷这样的材质做成的光滑盘片。然后,盘面上有一层磁性的涂层。数据就存储在这个磁性的涂层上。盘面中间有一个受电机控制的转轴。这个转轴会控制我们的盘面去旋转。
平时买硬盘的时候经常会听到一个指标,叫作这个硬盘的转速。我们的硬盘有 5400 转的、7200 转的,乃至 10000 转的。这个多少多少转,指的就是盘面中间电机控制的转轴的旋转速度,英文单位叫RPM,也就是每分钟的旋转圈数(Rotations Per Minute)。所谓 7200 转,其实更准确地说是 7200RPM,指的就是一旦电脑开机供电之后,硬盘就可以一直做到每分钟转上 7200 圈。如果折算到每一秒钟,就是 120 圈。
磁头(Drive Head)。数据并不能直接从盘面传输到总线上,而是通过磁头,从盘面上读取到,然后再通过电路信号传输给控制电路、接口,再到总线上的。
通常,一个盘面上会有两个磁头,分别在盘面的正反面。
盘面在正反两面都有对应的磁性涂层来存储数据,而且一块硬盘也不是只有一个盘面,而是上下堆叠了很多个盘面,各个盘面之间是平行的。每个盘面的正反两面都有对应的磁头。
悬臂(Actutor Arm)。悬臂链接在磁头上,并且在一定范围内会去把磁头定位到盘面的某个特定的磁道(Track)上。这个磁道是怎么来呢?想要了解这个问题,我们要先看一看我们的数据是怎么存放在盘面上的。
一个盘面通常是圆形的,由很多个同心圆组成,每一个圆圈都是一个磁道。每个磁道都有自己的一个编号。悬臂其实只是控制,到底是读最里面那个圆圈的数据,还是最外面圆圈的数据。

一个磁道,会分成一个一个扇区,上下平行的一个一个盘面的相同扇区叫一个柱面。
读取数据的过程
1.把盘面旋转到某一个位置。在这个位置上,悬臂可以定位到整个盘面的某一个子区间。一般把这个区间叫作几何扇区意思是,在“几何位置上”,所有这些扇区都可以被悬臂访问到。
2.把悬臂移动到特定磁道的特定扇区,也就在这个“几何扇区”里面,找到实际的扇区。找到之后,磁头会落下,就可以读取到正对着扇区的数据。
进行一次硬盘上的随机访问,需要的时间由两个部分组成。
1.平均延时(Average Latency)。这个时间是把盘面旋转,把几何扇区对准悬臂位置的时间。这个时间和机械硬盘的转速相关。随机情况下,平均找到一个几何扇区,需要旋转半圈盘面。上面 7200 转的硬盘,那么一秒里面,就可以旋转 240 个半圈。那么,这个平均延时就是
1s/240=4.17ms
1s / 240 = 4.17ms
1s/240=4.17ms
2.平均寻道时间(Average Seek Time),在盘面选转之后,悬臂定位到扇区的的时间。 HDD 硬盘的平均寻道时间一般在 4-10ms。
如果随机在整个硬盘上找一个数据,需要 8-14 ms。硬盘是机械结构的,只有一个电机转轴,也只有一个悬臂,所以没有办法并行地去定位或者读取数据。
那一块 7200 转的硬盘,我们一秒钟随机的 IO 访问次数,也就是
1s/8ms=125IOPS或者1s/14ms=70IOPS
1s / 8 ms = 125 IOPS 或者 1s / 14ms = 70 IOPS
1s/8ms=125IOPS或者1s/14ms=70IOPS
如果我们不是去进行随机的数据访问,而是进行顺序的数据读写,我们应该怎么最大化读取效率呢?
可以选择把顺序存放的数据,尽可能地存放在同一个柱面上。这样,只需要旋转一次盘面,进行一次寻道,就可以去写入或者读取,同一个垂直空间上的多个盘面的数据。
如果一个柱面上的数据不够,我们也不要去动悬臂,而是通过电机转动盘面,这样就可以顺序读完一个磁道上的所有数据。
Partial Stroking:根据场景提升性能
一般情况下,硬盘的寻道时间都比平均延时要长。
那么我们自然就可以想一下,有什么办法可以缩短平均的寻道时间。最极端的办法就是我们不需要寻道,也就是说,我们把所有数据都放在一个磁道上。比如,我们始终把磁头放在最外道的磁道上。这样,我们的寻道时间就基本为 0,访问时间就只有平均延时了。那样,我们的 IOPS,就变成了
1s/4ms=250IOPS
1s / 4ms = 250 IOPS
1s/4ms=250IOPS
不过呢,只用一个磁道,能存的数据就比较有限了。
所以,实践当中,我们可以只用 1/2 或者 1/4 的磁道,也就是最外面 1/4 或者 1/2 的磁道。这样,我们硬盘可以使用的容量可能变成了 1/2 或者 1/4。但是寻道时间,也变成了 1/4 或者 1/2,因为悬臂需要移动的“行程”也变成了原来的 1/2 或者 1/4,IOPS 就能够大幅度提升了。
这样通过软件去格式化硬盘,只保留部分磁道让系统可用的情况,可以大大提升硬件的性价比。
本文探讨了硬盘I/O性能的关键指标,包括数据传输率、响应时间和IOPS,重点比较了机械硬盘和固态硬盘的特点,并强调了在实际应用中,随机读写性能和IOPS对于服务器性能的重要性。作者还提供了Linux下监控和优化硬盘性能的方法,如使用iostat和iotop工具。
569

被折叠的 条评论
为什么被折叠?



