一、概述
磁盘接口
Linux磁盘接口一般分为两种:
- 并行:IDE(133MB/s)、SCSI(640MB/s); 设备名称hd*
- 串口:SATA(6Gbp/s) 、SAS(6Gp/s) 、USB(480MB/s); 设备名称sd*
串口的传输速度比并口的更块,为什么?
单个磁盘来说,由一个个的同心圆组成,一个同心圆就是一个磁道,每个磁道由多个扇区组成,每个扇区之间由没有磁性的间隙分隔。扇区有磁性物质,支持读和写操作。
盘面
硬盘一般会有一个或多个盘片,每个盘片可以有两个面(Side),即第1个盘片的正面称为0面,反面称为1面;第2个盘片的正面称为2面,反面称为3面…依次类推。每个盘面对应一个磁头(head)用于读写数据。第一个盘面的正面的磁头称为0磁头,背面称为1磁头;第二个盘片正面的磁头称为2磁头,背面称为3磁头,以此类推。盘面数和磁头数是相等的。
磁道
每个盘片的每个盘面被划分成多个狭窄的同心圆环,数据就是存储在这样的同心圆环上,我们将这样的圆环称为磁道(Track),每个盘面可以划分多个磁道。关机时磁头停留在硬盘的着陆区(Landing Zone),这个着陆区以前是位于离盘心最近的区域,不存放任何数据。
在每个盘面的最外圈,离盘心最远的地方是“0”磁道,向盘心方向依次增长为1磁道,2磁道,等等。硬盘数据的存放就是从最外圈开始。
扇区
根据硬盘规格的不同,磁道数可以从几百到成千上万不等。每个磁道上可以存储数KB的数据,但计算机并不需要一次读写这么多数据。在这一这基础上,又把每个磁道划分成若干弧段,每段称为一个扇区(Sector)。
每个磁道的扇区数量是一个常量,每个扇区的大小一般是4KB。扇区是磁盘基本的物理单元。
扇区是硬盘上存储的物理单位,每个扇区可存储128×2N次方(N=0,1,2,3)字节的数据。从DOS时代起,每扇区是128×22=512字节,现在已经成了业界不成文的规定。
也就是说即使计算机只需要硬盘上存储的某个字节,也须一次把这个字节所在的扇区中的全部512字节读入内存,再选择所需的那个字节。扇区的编号是从1开始,而不是0。 在硬盘磁道中,扇区号是按照某个间隔跳跃着编排。比如,2号扇区并不是1号扇区后的按顺序的第一个而是第八个,3号扇区又是2号扇区后的按顺序的第八个,依此类推,这个“八”称为交叉因子。( 数据读取经常需要按顺序读取一系列相邻的扇区(逻辑数据相邻)。如对磁道扇区按物理顺序进行编号,很有可能出现当磁头读取完第一个扇区后,由于盘片转速过快来不及读取下一个扇区,(要知道物理相邻扇区位置距离是极小的),必须等待转完一圈,这极大浪费了时间。所以就用交叉来解决这个问题。)
柱面
柱面其实是我们抽象出来的一个逻辑概念,前面说过,离盘心最远的磁道为0磁道,依此往里为1磁道,2磁道,3磁道....,不同面上相同磁道编号则组成了一个圆柱面,即所称的柱面(Cylinder)。
硬盘数据的读写是按柱面进行,即磁头读写数据时首先在同一柱面内从0磁头开始进行操作,依次向下在同一柱面的不同盘面(即磁头上)进行操作,只有在同一柱面所有的磁头全部读写完毕后磁头才转移到下一柱面,因为选取磁头只需通过电子切换即可,而选取柱面则必须通过机械切换。电子切换比从在机械上磁头向邻近磁道移动快得多。因此,数据的读写按柱面进行,而不按盘面进行。
块
将物理相邻的若干个扇区称为了一个块。操作系统读写磁盘的基本单位是扇区,而文件系统的基本单位是块(Cluster),存储系统都采用逻辑单元块来表示基本的数据单位,这样可以提高存储的效率。 块越大存储性能越好,但空间浪费严重。块越小性能相对越低,但空间利用率高。NTFS格式的文件系统簇的大小为4K。
二、磁盘性能因素
而磁盘的读写有3个步骤,即寻道时间 + 旋转延迟 + 传输时间
寻道时间Tseek
寻道时间,其实就是磁臂移动到指定磁道所需要的时间,目前磁盘的平均寻道时间一般在3-15ms
寻道时间=启动磁臂的时间+常数*所需移动的磁道数
旋转延迟Trotation
旋转延迟指的是把扇区移动到磁头下面的时间(取决于磁盘转速)
计算方式:7200 rpm的磁盘平均旋转延迟大约为60*1000/7200/2 = 4.17ms
传输时间Ttransfer
传输时间指的是从磁盘读出或将数据写入磁盘的时间
三、磁盘性能指标
IOPS
IOPS表示存储每秒传输IO的数量 IOPS通常对于小I/O,且传输I/O的数量比较大的情况下,是一个最主要的衡量指标,关注随机读写性能
而理论上磁盘的最大IOPS,即IOPS = 1000 ms/ (Tseek + Troatation)
例如7200转/分钟的 IOPS = 1000 / (3 + 60000/7200/2) = 140
吞吐量
Throughput吞吐量则表示每秒数据的传输总量 Throughput吞吐量衡量对于大I/O,特别是传输一定数据的时候最小化耗时非常有用,关注连续读写性能
每秒 I/O 吞吐量= IOPS* 平均 I/O SIZE
随机读写频繁的应用,如小文件存储(图片)、OLTP数据库、邮件服务器 顺序读写频繁的应用,传输大量连续数据,如电视台的视频编辑,视频点播VOD
四、磁盘性能优化
上面硬盘读写数据所分的三部分时间不难看出,大部分参数是和硬件相关的,操作系统无力优化。只有所需移动的磁道数是可以通过操作系统来进行控制的,所以减少所需移动的磁道数是减少整个硬盘的读写时间的唯一办法,可以通过调度算法和其他一些手动来优化。
调度算法
优化寻址操作,内核不会一旦接收到I/O请求后,就按照请求的次序发起块I/O请求。为此Linux实现了几种I/O调度算法,算法基本思想就是通过合并和排序I/O请求队列中的请求,以此大大降低所需的磁盘寻道时间.
常见的I/O调度算法包括Noop调度算法(No Operation)、CFQ(完全公正排队I/O调度算法)、DeadLine(截止时间调度算法)、AS预测调度算法等.
其他手段
局部原理
所谓的局部性原理分为时间和空间上的。由于程序是顺序执行的,因此当前数据段附近的数据有可能在接下来的时间被访问到。这就是所谓的空间局部性。而程序中还存在着循环,因此当前被访问的数据有可能在短时间内被再次访问,这就是所谓的时间局部性原理。
提前读(Read-Ahead)
提前读也被称为预读。根据磁盘原理我们不难看出,在磁盘读取数据的过程中,真正读取数据的时间只占了很小一部分,而大部分时间花在了旋转延迟和寻道时间上,因此根据空间局部性原理,SQL Server每次读取数据的时间不仅仅读取所需要的数据,还将所请求数据附近的数据进行读取。这在SQL Server中被称为预读。SQL Server通过预读可以有效的减少IO请求。
延迟写(Delayed write)
同样,根据时间局部性原理,最近被访问的数据有可能再次被访问,因此当数据更改之后不马上写回磁盘,而是继续放在内存中,以备接下来的请求读取或者修改,是减少磁盘IO的另一个有效手段,在SQL Server中,实现延迟写是buffer pool,当一个修改请求被commit之后,并不会立刻写回磁盘,而是将修改的页标记为“脏”,然后根据某种机制通过checkpoint或lazy writer写回磁盘,关于checkpoint和lazy writer的原理
五、从虚拟内存的角度理解磁盘和主存的数据交换
从虚拟内存的角度来说,虚拟页和磁盘中的块映射起来
当虚拟页被加载到内存的物理页的时候,就由DMA把虚拟内存对应的磁盘块加载到内存的对应地址的物理页中;
当物理页写回到磁盘时,也是由DMA把数据传输到磁盘控制器,由磁盘控制器写到磁盘块对应的扇区。
内存和磁盘交换数据的时候实际采用了内存的缓冲区来加速磁盘的访问速度,有了内存缓冲区,CPU要访问某个磁盘文件的某些数据,只需要提供该数据所处的磁盘块号,就可以从内存缓冲区寻找是否已经缓存了该磁盘块的内容
六、参考
linux学习之硬盘的存储原理和内部架构 - 云+社区 - 腾讯云cloud.tencent.com 磁盘IO那些事tech.meituan.com