一般情况下,机械硬盘的 IO 性能比固态硬盘要差不少,尤其在随机读写上的性能表现差距更大,但是机械硬盘的存储单价要比固态硬盘要低不少,性价比较高。
如果使用机械硬盘,优化磁盘读写的核心要点便是:尽量采用顺序读写,而不要采用随机读写,因为机械硬盘的磁头移动的时间开销远远大于文件传输的时间开销。kafka 和 hdfs 是利用这一原则的典型案例。
B+ 树是一种专门针对磁盘存储而优化的 N 叉排序树,以树节点为单位存储在磁盘中,从根开始查找所需数据所在的节点编号和磁盘位置,将其加载到内存中然后继续查找,直到找到所需的数据。B+ 树经常用于关系型数据库中的索引设计中,比如 MySQL 便是使用 B+ 树构造索引。
LSM 树可以看作是一个 N 阶合并树。
数据写操作(包括插入、修改、删除)都在内存中进行,并且都会创建一个新记录(修改会记录新的数据值,而删除会记录一个删除标志),这些数据在内存中仍然还是一棵排序树,当数据量超过设定的内存阈值后,会将这棵排序树和磁盘上最新的排序树合并。当这棵排序树的数据量也超过设定阈值后,和磁盘上下一级的排序树合并。合并过程中,会用最新更新的数据覆盖旧的数据(或者记录为不同版本)。
在需要进行读操作时,总是从内存中的排序树开始搜索,如果没有找到,就从磁盘上的排序树顺序查找。
在 LSM 树上进行一次数据更新不需要磁盘访问,在内存即可完成,速度远快于 B+ 树。当数据访问以写操作为主,而读操作则集中在最近写入的数据上时,使用 LSM 树可以极大程度地减少磁盘的访问次数,加快访问速度。
RAID(廉价磁盘冗余阵列)技术主要是为了改善磁盘的访问延迟,增强磁盘的可用性和容错能力。目前服务器级别的计算机都支持插入多块磁盘( 8 块或者更多),通过使用 RAID 技术,实现数据在多块磁盘上的并发读写和数据备份。
RAID 技术可以通过硬件实现,比如专用的 RAID 卡或者主板直接支持,也可以通过软件实现。
常用 RAID 技术有以下几种:
RAID0 数据在从内存缓冲区写入磁盘时,根据磁盘数量将数据分成 N 份,这些数据同时并发写入 N 块磁盘,使得数据整体写入速度是一块磁盘的 N 倍。读取时也一样,因此 RAID0 具有极快的数据读写速度,但是 RAID0 不做数据备份,N 块磁盘中只要有一块损坏,数据完整性就被破坏,所有磁盘的数据都会损坏。
RAID1 数据在写入磁盘时,将一份数据同时写入两块磁盘,这样任何一块磁盘损坏都不会导致数据丢失,插入一块新磁盘就可以通过复制数据的方式自动修复,具有极高的可靠性。
RAID10 结合 RAID0 和 RAID1 两种方案,将所有磁盘平均分成两份,数据同时在两份磁盘写入,相当于RAID1,但是在每一份磁盘里面的 N/2 块磁盘上,利用 RAID0 技术并发读写,既提高可靠性又改善性能,不过 RAID10 的磁盘利用率较低,有一半的磁盘用来写备份数据。
RAID3 在数据写入磁盘的时候,将数据分成 N-1 份,并发写入 N-1 块磁盘,并在第 N 块磁盘记录校验数据,任何一块磁盘损坏(包括校验数据磁盘),都可以利用其他 N-1 块磁盘的数据修复。 但是在数据修改较多的场景中,修改任何磁盘数据都会导致第 N 块磁盘重写校验数据,频繁写入的后果是第 N 块磁盘比其他磁盘容易损坏,需要频繁更换,所以 RAID3 很少在实践中使用。
RAID5 RAID5 和 RAID3 很相似,但是校验数据不是写入第 N 块磁盘,而是螺旋式地写入所有磁盘中。这样校验数据的修改也被平均到所有磁盘上,避免 RAID3 频繁写坏一块磁盘的情况。
RAID6 RAID6 和 RAID5 类似,但是数据只写入 N-2 块磁盘,并螺旋式地在两块磁盘中写入校验信息(使用不同算法生成)。