单机数据持久-磁盘驱动器
2023-1-15
| 2023-8-2
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 
 

接口

所有现代驱动器的基本接口都很简单。驱动器由大量扇区(512字节块)组成,每个扇区都可以读取或写入。在包含n个扇区的磁盘上,扇区从0到n−1编号。因此,我们可以将磁盘视为一组扇区,0到n−1是驱动器的地址空间。
多扇区操作是可能的,实际上许多文件系统一次读取或写入4KB(或更多)。但在更新磁盘时,驱动器制造商唯一保证的是单个扇区的写入是原子的。因此,如果发生不合时宜的掉电,则只能完成较大写入的一部分 (有时称为不完整写入)。
通常可以假设访问驱动器地址空间内的连续块(顺序读取或写入)是最快的访问模式,并且通常比任何更随机的访问模式快得多。
 

基本构成

一个磁盘可能有一个或多个盘片(platter),每个盘片有两面,称为表面。这些盘片通常由一些硬质材料(如铝)制成,然后涂上薄薄的磁性层,即使驱动器断电,驱动器也能持久存储数据位。
所有盘片都围绕主轴(spindle)连接在一起,主轴以一个恒定的速度旋转盘片。旋转速率通常以每分钟转数(Rotations Per Minute,RPM)来测量,典型的现代数值在7200~15000 RPM范围内。
数据在扇区的同心圆中的每个表面上被编码,称这样的同心圆为一个磁道(track)。一个表面包含数以千计的磁道,紧密地排在一起。
磁盘的读写过程由磁头(disk head)完成,驱动器的每个表面有一个这样的磁头。磁头连接到单个磁盘臂(disk arm)上,磁盘臂在表面上移动,将磁头定位在期望的磁道上。
 

工作原理

假设有一个单一磁道的简单磁盘。该磁道只有12个扇区,每个扇区的大小为512字节,用0到11的数字表示。
 
notion image
notion image
单个盘片围绕主轴旋转,电机连接到主轴。我们希望能够读取或写入这些扇区,因此需要一个连接到磁盘臂上的磁头
单磁道延迟:旋转延迟
假设现在收到读取块0的请求,磁盘应如何处理该请求?
它必须等待期望的扇区旋转到磁头下。这种等待在现代驱动器中经常发生,并且是I/O服务时间的重要组成部分,它有一个特殊的名称:旋转延迟(rotational delay,有时称为rotation delay)。在上图中,如果完整的旋转延迟是R,那么磁盘必然产生大约为R/2的旋转延迟,以等待0来到读/写磁头下面。
 
多磁道:寻道时间
notion image
磁盘只有一条磁道,这是不太现实的,现代磁盘有数以百万计的磁道。磁头当前位于最内圈的磁道上。下一个磁道包含下一组扇区,最外面的磁道包含最前面的扇区。
假设需要读取扇区11。为了服务这个读取请求,驱动器必须首先将磁盘臂移动到正确的磁道,这个过程也即所谓的寻道(seek)。寻道和旋转都是最昂贵的磁盘操作之一。
寻道有许多阶段:首先是磁盘臂移动时的加速阶段,随着磁盘臂全速移动而惯性滑动,然后随着磁盘臂减速而减速,最后在正确的磁道上停下来。停放时间(settling time)通常不小,例如0.5~2ms,因为驱动器必须确定找到正确的磁道。
在寻道过程中,盘片也会跟着一起旋转,在这个例子中,大约旋转了3个扇区。因此,寻道完成时,磁头下方是扇区9。接着只需再等待短暂的转动延迟,当扇区11经过磁头时,数据才开始真正读写,称为传输(transfer)。因此,完整的I/O时间图:首先寻道,然后等待转动延迟,最后传输。
 
一些其他细节
notion image
许多驱动器采用某种形式的磁道偏斜(track skew),以确保即使在跨越磁道边界时,也可以很方便地顺序读取。从一个磁道切换到另一个磁道时,如果没有这种偏斜,所需的下一个块已经旋转到磁头后的位置,因此驱动器将不得不等待整个旋转延迟,才能访问下一个块。
外圈磁道通常比内圈磁道具有更多扇区,这是几何结构的结果。这通常被称为多区域(multi-zoned)磁盘驱动器,其中磁盘被组织成多个区域,区域是表面上连续的一组磁道。每个区域每个磁道具有相同的扇区数量,并且外圈区域具有比内圈区域更多的扇区。
任何现代磁盘驱动器都有一个重要组成部分,即它的缓存(cache),由于历史原因有时称为磁道缓冲区(track buffer)。该缓存只是少量的内存(通常大约8MB或16MB),驱动器可以使用这些内存来保存从磁盘读取或写入磁盘的数据。例如,当从磁盘读取扇区时,驱动器可能决定读取该磁道上的所有扇区并将其缓存在其存储器中。这样做可以让驱动器快速响应所有后续对同一磁道的请求。
在写入时,驱动器面临一个选择:它应该在将数据放入其内存之后还是实际写入磁盘之后,回报写入完成?前者被称为后写(write back)缓存,后者则称为直写(write through)。后写缓存有时会使驱动器看起来“更快”,但可能有风险。如果文件系统或应用程序要求将数据按特定顺序写入磁盘以保证正确性,后写缓存可能会导致问题。
 
 

I/O时间和性能

关于磁盘驱动器的有关I/O的时间和性能问题:
  1. I/O总时间 = 寻道时间 + 旋转时间 + 传输时间,通常前两者的延迟大致相当,同时远大于传输时间。
  1. 由上一条可以得出,磁盘的随机和顺序工作负载之间的驱动性能差距很大,对于普通磁盘来说一般在几百倍左右。
  1. 高端的“性能”驱动器与低端的“容量”驱动器之间的性能差异很大。
 
 

磁盘调度

由于I/O的高成本,操作系统在决定发送给磁盘的I/O顺序方面历来发挥重要作用。给定一组I/O请求,磁盘调度程序检查请求并决定下一个要调度的请求。
与任务调度不同,对于磁盘调度,可以很好地猜测磁盘请求需要多长时间。通过估计请求的查找和可能的旋转延迟,磁盘调度程序可以知道每个请求将花费多长时间,因此选择先服务花费最少时间的请求。因此,磁盘调度程序将尝试在其操作中遵循SJF(最短任务优先)的原则。
 
SSTF:最短寻道时间优先
一种早期的磁盘调度方法被称为最短寻道时间优先(Shortest-Seek-Time-First,SSTF)。SSTF按磁道对I/O请求队列排序,选择在最近磁道上的请求先完成。例如,假设磁头当前位置在内圈磁道上,请求扇区21和2,那么会首先发出对21的请求,等待它完成,然后发出对2的请求。
notion image
但SSTF 不是万能的。第一个问题,主机操作系统无法利用驱动器的几何结构,而是只会看到一系列的块。幸运的是,这个问题很容易解决。操作系统可以简单地实现最近块优先(Nearest-Block-First,NBF),而不是SSTF,然后用最近的块地址来调度请求。
第二个问题更为根本:饥饿(starvation)。想象一下,在我们上面的例子中,是否有对磁头当前所在位置的内圈磁道有稳定的请求。然后,纯粹的SSTF 方法将完全忽略对其他磁道的请求。
如何实现类SSTF 调度,但避免饥饿?
 
电梯(SCAN 或C-SCAN)
这个问题的答案是很久以前得到的,并且相对比较简单。该算法最初称为SCAN,简单地以跨越磁道的顺序来服务磁盘请求。将一次跨越磁盘称为扫一遍。因此,如果请求的块所属的磁道在这次扫一遍中已经服务过了,它就不会立即处理,而是排队等待下次扫一遍。
SCAN 有许多变种,所有这些变种都是一样的。例如,Coffman 等人引入了F-SCAN,它在扫一遍时冻结队列以进行维护。这个操作会将扫一遍期间进入的请求放入队列中,以便稍后处理。这样做可以避免远距离请求饥饿,延迟了迟到(但更近)请求的服务。
C-SCAN 是另一种常见的变体,即循环SCAN(Circular SCAN)的缩写。不是在一个方向扫过磁盘,该算法从外圈扫到内圈,然后从内圈扫到外圈,如此下去。
由于现在应该很明显的原因,这种算法(及其变种)有时被称为电梯(elevator)算法,因为它的行为像电梯,电梯要么向上要么向下,而不只根据哪层楼更近来服务请求。试想一下,如果你从10 楼下降到1 楼,有人在3 楼上来并按下4 楼,那么电梯就会上升到4 楼,因为它比1 楼更近!如你所见,电梯算法在现实生活中使用时,可以防止电梯中发生战斗。在磁盘中,它就防止了饥饿。
然而,SCAN 及其变种并不是最好的调度技术。特别是,SCAN(甚至SSTF)实际上并没有严格遵守SJF 的原则。具体来说,它们忽视了旋转。
如何同时考虑寻道和旋转,实现更接近SJF 的算法?
 
 
SPTF:最短定位时间优先
notion image
磁头当前定位在内圈磁道上的扇区30上方。因此,调度程序必须决定:下一个请求应该为安排扇区16(在中间磁道上)还是扇区8(在外圈磁道上)。接下来应该服务哪个请求?
答案当然是“视情况而定”。这里的情况是旋转与寻道相比的相对时间。如果在我们的例子中,寻道时间远远高于旋转延迟,那么SSTF(和变体)就好了。但是,想象一下,如果寻道比旋转快得多。然后,在我们的例子中,寻道远一点的、在外圈磁道的服务请求8,比寻道近一点的、在中间磁道的服务请求16 更好,后者必须旋转很长的距离才能移到磁头下。
在现代驱动器中,正如上面所看到的,查找和旋转大致相当(当然,视具体的请求而定),因此SPTF 是有用的,它提高了性能。然而,它在操作系统中实现起来更加困难,操作系统通常不太清楚磁道边界在哪,也不知道磁头当前的位置(旋转到了哪里)。因此,SPTF通常在驱动器内部执行。
 
 

其他调度问题

在较早的系统中,操作系统完成了所有的磁盘调度。然而在现代系统中,磁盘可以接受多个分离的请求,而且它们本身具有复杂的内部调度程序。因此,操作系统调度程序通常会选择它认为最好的几个请求,并将它们全部发送到磁盘。磁盘然后利用其磁头位置和详细的磁道布局信息等内部知识,以最佳可能(SPTF)顺序服务于这些请求
磁盘调度程序执行的另一个重要相关任务是I/O合并(I/O merging)。例如,设想一系列请求读取块33,然后是8,然后是34。在这种情况下,调度程序应该将块33和34的请求合并(merge)为单个两块请求。调度程序执行的所有请求都基于合并后的请求。合并在操作系统级别尤其重要,因为它减少了发送到磁盘的请求数量,从而降低了开销。
现代调度程序关注的最后一个问题是:在向磁盘发出I/O之前,系统应该等待多久?有人认为,即使只有一个磁盘I/O,也应立即向驱动器发出请求,这种方法被称为工作保全(work-conserving)。然而,研究表明,有时最好等待一段时间,即所谓的非工作保全(non-work-conserving)方法。通过等待,新的或“更好”的请求可能会到达磁盘,从而提高整体效率。当然,决定何时等待以及等待多久,可能会很棘手,需要大量实践和观察。
 
  • 计算机基础
  • 操作系统
  • 单机数据持久-I/O 设备单机数据持久-RAID
    目录