上图描述了磁盘的整体结构。磁盘由多个盘片组成,其中一个盘片有正反两个盘面,每个盘面上有一个磁头,盘片的每个盘面被划分成多个同心圆,也就是磁道,每个磁道又被划分成若干弧段, 每段称为一个扇区。柱面是指不同盘面上相同磁道编号的组合,簇是指物理相邻的若干个扇区。
磁盘空间主要通过以下 4 个属性计算得出:
-
盘面数量
-
磁道数量
-
扇区数量
-
扇区大小
例如,某磁盘具有以下属性:
-
8 个盘片,16 个盘面。
-
每个盘面有 2^16=65536 个磁道。
-
每个磁道 256 个扇区。
-
每个扇区 4096 个字节。
那么这块磁盘总空间为:
16 × 65536 × 256 × 4096Bytes = 1TB
日常使用磁盘中,特别是在读写磁盘操作过程中,偶尔会听到磁盘里面会发出一些噪音,这是磁盘的磁头在不停寻址产生的高速旋转。
磁盘的性能主要受以下因素的影响:
-
寻道时延
磁臂移动到指定磁道所需要的时间。
-
旋转时延
把扇区移动到磁头下面的时间。
-
传输时延
从磁盘读出或将数据写入磁盘的时间。
所以总时延 = 寻道时间 + 旋转延迟 + 传输时间。
虽然磁盘的性能由自身决定,但可以通过一些外部的方法对磁盘的使用性能进行优化,我们知道磁盘在使用上主要的性能问题是磁盘访问 IO,因此,解决思路就是在相同访问数据量的情况下,降低磁盘 IO 的开销。
-
可以将磁盘的数据缓存到主存中,通过操作主存中的数据,定期批量的刷新到磁盘保存,了解数据库系统的同学应该知道,这种方式跟数据库的 checkpoint 机制很相似。
-
通过一些算法优化磁盘的访问,例如使用多盘来让更多的磁头同时参与访问磁盘块,或者将需要访问的块放到同一个柱面来降低寻道和旋转的时间等。
总而言之,所有方法的原则就是降低磁盘 IO 或者提高磁盘数据的访问。
磁盘的故障一般分为以下几个方面:
-
间断性故障
反复读取间断性成功。
-
介质损坏
存储数据的扇区中一个或多个二进制位永久损坏,这种故障无法通过重复读取来解决。
-
写故障
不能写入扇区,也不能检索写过的扇区。
-
磁盘崩溃
整个磁盘不能读写。
对于上述磁盘读写错误的故障,实际中也是有一些检测机制来发现故障问题。
-
校验和技术(checksum),原理是在数据的最后加上根据数值内容进行的某种数学的叠加计算。
这里介绍一种简单的数字校验和技术:奇偶校验和。
如上图所示,假设有二进制内容 01101000,使用 1 位的奇偶位,如果二进制内容中有奇数个 1,那么认为数据具有奇数奇偶性,奇偶位为 1,也就是 011010001;如果数值中有偶数个 1,那么认为数据具有偶数奇偶性,奇偶位为 0,也就是 111011100。
那磁盘在读取数据时,因为已知二进制内容奇偶性,假设二进制内容 01101000 发生了变化,那么通过计算奇偶位后,发现与原来的奇偶位不一致,就可以认为磁盘发生了读故障。
当然,一个奇偶位只有 50% 的正确率,比如 01101000 发生变化的位数有 2 位,变成了 01111010,计算后的奇偶位还是 1,整体的奇偶性并没有变化,但实际上二进制内容已经发生变换,因此故障也就无法检测,这种场景可以通过增加奇偶位的数量来解决。例如增加了 8 位的奇偶位,则检测出错的概率是 1/2^8,以此类推。
-
稳定存储,可以简单理解为扇区数据的冗余,例如下图中的 X 扇区,使用两个扇区来冗余避错。这跟数据库中多副本的原理是一样的。