第 38 章 廉价冗余磁盘阵列(RAID)

简介

廉价冗余磁盘阵列(RAID,Redundant Array of Inexpensive Disks)使用多个磁盘共同构建更快、更大、更可靠的磁盘系统。

从外部看,RAID 对主机系统是透明的,表现为一个线性的块数组,就像一个大磁盘。这种透明性极大地提高了 RAID 的可部署性,无须修改操作系统和客户端应用程序即可直接替换原有磁盘。在内部,RAID 是一个复杂的专用计算机系统,包含微控制器、易失性内存(如 DRAM)、非易失性内存以及专用的奇偶校验逻辑电路。

故障模型与评估维度

为了理解和比较不同的 RAID 方法,我们假设使用故障—停止(fail-stop)故障模型。在该模型下,磁盘只有工作和故障两种状态。当磁盘发生故障时,数据永久丢失,且 RAID 控制器能立即检测到该故障。

评估每种 RAID 设计通常从以下三个维度进行:

  • 容量:给定 N 个磁盘,客户端可用的有效容量。
  • 可靠性:系统能够容忍的磁盘故障数量。
  • 性能:分为单请求延迟和稳态吞吐量。稳态吞吐量主要在两种典型工作负载下评估:顺序(Sequential)和随机(Random)。假设单个磁盘的顺序吞吐量为 S,随机吞吐量为 R。

RAID 0 级:条带化

RAID-0 不提供冗余,通过将块在磁盘上轮转分布(条带化,Striping)来最大化并行性。

以 4 个磁盘为例,块按如下方式分布:

磁盘 0磁盘 1磁盘 2磁盘 3
0123
4567
891011
12131415

同一行中的块称为一个条带(stripe),例如块 0、1、2、3 在同一条带中。给定逻辑块地址 A,可以通过以下公式计算其物理位置:

磁盘   = A % 磁盘数
偏移量 = A / 磁盘数  (整数除法)

大块大小(Chunk Size)

大块大小是指在移动到下一个磁盘之前,在单个磁盘上连续放置的数据量。大块大小主要影响性能:

  • 较小的大块:单个文件跨多个磁盘条带化,增加了单文件读写的并行性,但整个请求的定位时间由所有驱动器上的最大定位时间决定,会有所增加。
  • 较大的大块:减少了文件内的并行性,但降低了定位时间(文件可能只需访问单个磁盘)。

确定最佳大块大小需要大量关于工作负载的知识,实践中大多数阵列使用 64KB 左右的大块大小。

性能分析

  • 容量:N
  • 可靠性:0(任何磁盘故障都会导致数据丢失)
  • 吞吐量:顺序读写 N·S,随机读写 N·R
  • 延迟:读 T,写 T(请求直接重定向到单个磁盘,与单磁盘延迟相同)

RAID-0 是性能和容量的上限,是与其他 RAID 级别比较的基准。

RAID 1 级:镜像

RAID-1 通过为每个逻辑块保留多个物理副本(通常为两个)来提供冗余,数据在镜像对之间条带化。

磁盘 0磁盘 1磁盘 2磁盘 3
0011
2233
4455
6677

磁盘 0 和磁盘 1 互为镜像,磁盘 2 和磁盘 3 互为镜像。这种布局有时称为 RAID-10(RAID 1+0),即先镜像再条带化。另一种常见布局是 RAID-01(RAID 0+1),即先条带化再镜像。

读取时,RAID 可以从任一副本读取,可以利用所有磁盘。写入时,必须同时更新两个副本,两次写入可以并行进行。

一致更新问题

在更新多个磁盘时,如果写入期间发生掉电,可能导致两个副本不一致(一个是新版本,另一个是旧版本)。解决方法是使用预写日志(Write-ahead log),在实际写入前先记录操作。大多数 RAID 硬件通过少量电池备份的非易失性 RAM 来实现,避免了将日志写入磁盘的高昂代价。

性能分析

  • 容量:N/2
  • 可靠性:至少容忍 1 个磁盘故障,最多可容忍 N/2 个(取决于故障磁盘的分布)
  • 吞吐量
    • 顺序读写:(N/2)·S。顺序读取时,为了保持数据顺序,每个磁盘只能处理每隔一个的块请求,在跳过的块上空转,因此只能达到峰值带宽的一半。
    • 随机读:N·R(可将读请求分布在所有磁盘上)
    • 随机写:(N/2)·R(每次逻辑写入变为两次物理写入)
  • 延迟:读 T,写 T(写入时两个物理写入并行,但延迟略高于单磁盘,因受限于两次写入中最差的寻道和旋转延迟)

RAID 4 级:通过奇偶校验节省空间

RAID-4 使用一个专用的奇偶校验(Parity)磁盘存储冗余信息,以较少的容量损失来换取可靠性。

注意:由于奇偶校验本质上只提供了一个数学方程(偶数规则),因此 RAID-4(以及基于相同原理的 RAID-5)最多只能容忍 1 块硬盘发生故障。如果同时损坏 2 块盘,将出现两个未知数,数据将无法恢复。

磁盘 0磁盘 1磁盘 2磁盘 3磁盘 4(奇偶)
0123P0
4567P1
891011P2
12131415P3

奇偶校验原理(XOR)

RAID-4 本质上是对所有数据盘的同一个位置(每一位)进行对齐计算,生成一个同样大小的校验块。通过异或(XOR)运算,系统强制要求同一行所有盘(包括校验盘)在相同位置的 1 的总数始终为偶数:

C0C1C2C3P (校验位)
0010111011
1001000110
  • P0(11): 第1列两个1补1,第2列一个1补1,结果为11
  • P1(10): 第1列一个1补1,第2列两个1补0,结果为10

数据恢复:当硬件报错提示某块盘物理损坏时,RAID 控制器只需读取剩余盘和校验盘的对应位。根据“总数必须是偶数”的规则,就能完美反推出丢失位置的 0 或 1。对于 4KB 的数据块,则是对块中每个比特位批量执行此操作。

写入方式

全条带写入(full-stripe write):当一次性写满一整行(所有数据盘)时,RAID-4 可直接算出新的校验块并一起写入。这是最高效的写入方式,顺序写入吞吐量可达 (N-1)·S。

小写入问题(small-write problem):当只修改条带中的一小块数据时,为了维持“偶数规则”,必须同步修改校验块。这需要使用 减法奇偶校验(subtractive parity) 方法:

  1. 读取旧数据块(C_old)和旧奇偶校验块(P_old)
  2. 计算新奇偶校验:
  3. 将新数据块和新奇偶校验块写入磁盘

每次小写入需要 4 次物理 I/O(2 次读 + 2 次写)。更致命的是,任何数据盘的修改都必须排队去更新那块唯一的校验盘。这导致校验盘成为全局的“单点瓶颈”,使得随机写入操作被迫序列化。

性能分析

  • 容量:N - 1
  • 可靠性:1
  • 吞吐量
    • 顺序读写:(N-1)·S
    • 随机读:(N-1)·R
    • 随机写:(1/2)·R(奇偶校验磁盘每个逻辑 I/O 需执行 2 次 I/O,成为瓶颈)
  • 延迟:读 T,写 2T(先并行读旧数据和旧奇偶,再并行写新数据和新奇偶)

RAID 5 级:旋转奇偶校验

RAID-5 与 RAID-4 的工作原理基本相同,唯一的区别是将奇偶校验块跨所有驱动器旋转分布,从而消除了专用奇偶校验磁盘的瓶颈。

磁盘 0磁盘 1磁盘 2磁盘 3磁盘 4
0123P0
567P14
1011P289
15P3121314
P416171819

每个条带的奇偶校验块轮流放置在不同的磁盘上,使得多个并发写入请求可以访问不同磁盘上的奇偶校验块,从而实现并行。

为什么能实现并行?

在 RAID-4 中,所有写入操作都必须访问同一块固定的校验盘(如磁盘 4),导致物理磁头冲突,只能排队串行。而在 RAID-5 中,校验块被打散。例如,同时写入块 1 和块 10 时:

  • 写入块 1 需要占用 磁盘 1(数据)和 磁盘 4(校验块 P0)。
  • 写入块 10 需要占用 磁盘 0(数据)和 磁盘 2(校验块 P2)。 两组操作需要的物理磁盘完全没有交集,因此可以同时读写,真正实现了并发。

性能分析

  • 容量:N - 1(与 RAID-4 相同)
  • 可靠性:1(与 RAID-4 相同)
  • 吞吐量
    • 顺序读写:(N-1)·S(与 RAID-4 相同)
    • 随机读:N·R(所有磁盘均可参与读取,比 RAID-4 略好)
    • 随机写:(N/4)·R(消除了单盘瓶颈,但每次写入仍需 4 次 I/O)
  • 延迟:读 T,写 2T(与 RAID-4 相同)

由于 RAID-5 在几乎所有情况下都优于或等于 RAID-4,它已基本取代了市场上的 RAID-4。唯一例外是系统确定只会执行顺序大写入的场景,此时 RAID-4 因构建稍简单而偶有使用。

总结

各级 RAID 的核心特征对比(假设单盘请求延迟为 T):

指标RAID-0RAID-1RAID-4RAID-5
容量NN/2N - 1N - 1
可靠性01(肯定),N/2(运气好)11
顺序读N·S(N/2)·S(N-1)·S(N-1)·S
顺序写N·S(N/2)·S(N-1)·S(N-1)·S
随机读N·RN·R(N-1)·RN·R
随机写N·R(N/2)·R(1/2)·R(N/4)·R
读延迟TTTT
写延迟TT2T2T

选择 RAID 级别取决于最终需求:

  • 追求极致性能且不关心可靠性:选择 RAID-0。
  • 需要随机 I/O 性能和高可靠性,且能接受容量减半:选择 RAID-1。
  • 追求容量和可靠性最大化,且以顺序 I/O 为主:选择 RAID-5。
  • 工作负载以顺序大写入为主且希望简化实现:可考虑 RAID-4。