
这章如名字,主要讲的是磁盘冗余阵列,也就是我们常说的RAID。一种扩展磁盘的容量、提升磁盘可靠性的技术。
RAID存在RAID0到RAID6等多种方案。评估一个RAID方案,主要从容量、可靠性、性能这三个方面。RAID的特点和前面的一些虚拟化一样,将多个磁盘虚拟化为一个磁盘,来对上游提供服务。
RAID 0 条带化分块
RAID0是最基础的思路,实现的功能也很简单,对多个磁盘进行合并。他使用了**条带化(stripe)**的方式来对多个硬盘进行分段以及分块,将多个磁盘组合并按次序进行标记分段,然后存储数据时只要使用对应分段即可。

可以看到,跨越4个磁盘,我们通过分段让他们依旧有了连续性关系,所以我们就可以像操作一个磁盘那样操作4个磁盘了。
这里会有一个关键的权衡:如何选择每段的大小?首先注意一点,不同物理磁盘是可以并发读写的。所以,段分段过小时,我们可以拥有更好的并发性,但是会过多的跨越磁盘读取数据。段分段过大时,我们读取大文件会有更好的连续性,但是也会因为丧失并发性而失去一部分性能,并且性能此时就纯依赖于一个磁盘的性能了。
一个极端的例子可以说明这个情况:当我们的一个段时4kb时,此时读取一个16kb的文件,刚好是0-3四个分段。在4个磁盘并发读取的情况下,性能可以是接近4倍(因为还需要将数据合并,会有一定开销)。
评估RAID 0
我们评估磁盘的性能与之前一样,分别要考虑2个场景:顺序、随机。
给定单个磁盘的性能,我们来进行一下计算单个磁盘的S和R,其中S表示顺序sequential,R表示随机random。
Average seek time 7 ms
Average rotational delay 3 ms
Transfer rate of disk 50 MB/s
从吞吐量的角度看性能(多磁盘间可以并发读写)。在整个RAID0下,访问整个RAID0和访问单个磁盘的延迟大致相同,所以RAID0的实际S=N·S,R=N·R, 基本是线性的提升。
所以我们总结下RAID0表现:
容量:线性提升,RAID容量=单个磁盘·N
可靠性:0,没有任何可靠性措施
性能:线性提升,RAID性能=单个磁盘·N
RAID 1 镜像
RAID1开始,带上了机制以保证可靠性。

可以看到,通过巧妙的分块,我们对每个分块做了一份冗余。每个分块我们都会保存一份镜像在另外的硬盘上。
评估RAID 1
依旧从3个角度去评估。我们在这里只评估所有数据仅有一份冗余的情况,因为更多份冗余的场景也很容易按照这种方式去计算
容量
很显然,容量的降低取决于我们镜像的数量,在只备份一份的情况下,我们的容量变为了N/2。
可靠性
从可靠性上来看,RAID1最佳情况下可以容忍N/2的故障。即D0和D2都挂了。最差可以容忍1的故障,即D0-D3任意一个挂了。
性能
这里有一点比较特殊,因为我们提到了跨磁盘之间的操作可能是并行的,那么好像读或者写2份在同一个磁盘的数据好像对性能的影响微乎其微?
顺序读
但是其实不是这样,考虑到我们要计算综合吞吐的话,在顺序读时,因为磁盘分块被我们分割开了,哪怕是顺序读,0-1-2-3-4-5-6也可能跨了非常多的磁盘(D0,D2,D0,D2,D0,D2),此时考虑到还有额外2种情况:
- 读取时因为有2份数据,所以可能不只是2个盘,而是D0D1D2D1D3
- 磁盘本身会旋转,本身的顺序读被完全割裂了
所以顺序读的实际吞吐可能接近
顺序写
顺序写也是一样,因为要保证2份数据同时写完才算写成功,即使可以并发写,但是会带来另一个磁盘可能刚好错过扇区的成本,所以顺序写的吞吐也是
随机
随机读反而不受影响,因为本来就要承担该承担的一切,所以还是N·R
随机写于顺序写一样,也是
ps:这里文中的计算看看大概思路了解需要考虑那些额外因素就好,实际现实上不能这么算,加深对磁盘运作机制的理解就可以
RAID 4 通过奇偶校验节省空间
RAID4是一种优化,通过奇偶校验节省副本所需要的空间

奇偶校验可以使用一个额外的盘上的分块,来存储前面一系列分块的奇偶校验和,以此来节省空间。
奇偶校验保存方式
- 对于同一行的分块,都在Disk4上有一个额外的分块,来保存奇偶校验值
- 奇偶校验值保存了前面D0-D3中对应分段的每一个bit位的奇偶校验值
奇偶校验位的含义以及计算
-
奇偶校验位为0或1
-
奇偶校验位与它所对应的bit,1的数量必须是偶数
-
快速计算的话,只需要对前面的位整个进行异或XOR,得到的就是奇偶校验位,比如下图,0^0^1^1=0,0^0^1^0=1
Disk0 Disk1 Disk2 Disk3 Disk4(奇偶校验bit) 0 0 1 1 0 0 0 1 0 1
奇偶校验位如何做到冗余
- 奇偶校验位可以完成1个盘损坏情况下的冗余,可以认为是1档冗余
- 因为奇偶校验位的特性(奇偶校验位bit与所有数据bit中1的数量必须为偶数),所以我们可以简单的拥有以下恢复策略当某个盘不可读取时,再次检查整行的值
- 如果此时1的数量为奇数,说明丢失的那bit是1
- 相反,如果此时1的数量还是为偶数,那么说明丢失的那bit是0
评估RAID 4
容量
无论多少个磁盘,奇偶校验只需要一个额外磁盘保存奇偶校验位,所以容量是(N−1)·B
可靠性
从原理上来说,奇偶校验位的可靠性最多允许一个disk坏掉
性能
顺序读
顺序读我们可以正常操作除奇偶校验盘外的所有,所以是(N−1)·SMB/s
顺序写
顺序写时,考虑到一种情况:我们可以直接一行一行块的写,即直接从分块0写到分块P0,这个时候直接在写前面的时候也就把奇偶校验计算出来了,所以写的速度也是(N−1)·SMB/s
随机读
随机读与上面类似,所以还是(N-1)·R
随机写
随机写十分复杂,要考虑的点非常多,是一个重点。
首先是如何得到新奇偶校验的值
在写入某个块时,奇偶校验位的值也需要被更新,我们想一下,最基本的更新策略可以是这样:
- 更新某个分块(比如说Disk0上的0)时,更新后,我们读取同一行的所有数值,重新计算奇偶校验并写入P0
但是这显然成本过高了,更新一个分块,反而要读取整行所有的分块吗?考虑到奇偶校验和的来源,我们可以有另一种简单的办法
- 通过这个分块的原值、新写入的值、奇偶校验位的值,来计算新的奇偶校验位——
然后,写入会存在很明显的瓶颈
在随机写场景,当随机写连续发生在2个disk时,按照我们之前的估计,2个disk本身是支持并发一起写的,但是引入奇偶校验后,会出现问题,如下图

我们会发现,及时4和13因为分别位于D0和D1,他们之间可以并发进行写,但是因为他们都需要更新奇偶校验和,所以都需要在D4上去写,D4成为了随机写的瓶颈!
事实上,在这种场景下,整个随机写最终都会成为在D4上的串行写,所以我们随机写的性能,不只达不到N*R,甚至小于了单个磁盘的R,考虑到每次写入奇偶校验位时,都需要先读取原来的校验位来做计算,所以实际随机写的性能大约是(因为又要读一次又要写一次,所以大概是一半)。
ps:还是那句话,这种算法知道考虑的点就行,实际的值准不准确别过于认真
RAID 5 轮流保存奇偶校验位
RAID5也是一种优化,来优化RAID4的性能瓶颈

参考这个图,RAID 5不再使用一个固定的盘来保存奇偶校验位,而是每个盘轮流在一行中使用一个分段来保存奇偶校验位。在评估之前,我们首先就可以发现它主要就是规避了RAID4中使用一个盘来做奇偶校验盘的单写问题。
评估RAID 5
容量
与RAID 4一样
可靠性
与RAID 4一样
性能
除了随机写以外,基本都与与RAID 4一样,随机读会稍微好一些,因为我们现在可以读所有磁盘了
随机写
随机写会提升不少性能,因为我们避免了写阻塞在一个盘上的问题,但是因为奇偶校验位会在任意盘上,所以我们在大量随机写时,所有盘都在狂飙(写D0时要写D4的校验,写D4时又要写D0的校验,互相之间都是套娃)。我们预估这种情况下,实际写入的速度估计是
RAID总结

RAID是在软件层(磁盘控制读取写入)做一系列设计,去实现多磁盘的组合使用,其中几个主要方案就是这章中介绍的,其他的RAID2、3、6可以自己再去了解下,但是核心思路都已经在本章中的几个方案里提到了。
RAID方案的取舍也是取决于你对容量、性能、可靠性的权衡取舍。个人感觉对于家里的NAS来说,基本上RAID-5就是最佳方案了。
分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 787 天
部分内容可能已过时