1本章要解决的问题
如何构建一个大、快、可靠的存储系统?关键技术是什么?不同做法之间有哪些权衡?
How can we make a large, fast, and reliable storage system? What are the key techniques? What are trade-offs between different approaches?
上一章我们看到,一块磁盘又慢(随机 I/O 只有不到 1MB/s)、又有限(容量固定),还会坏(坏了数据就没了)。我们总是希望磁盘更快、更大、更可靠。1980 年代后期,伯克利的 Patterson、Katz 和当时的学生 Gibson 提出了 RAID(Redundant Array of Inexpensive Disks,廉价冗余磁盘阵列):把多块便宜的磁盘组合起来,对外假装成"一块"更好的磁盘。
本章是持久化部分承上启下的一环:它建立在第 37 章的磁盘性能模型之上(顺序带宽 S、随机带宽 R),又把"透明地在下层提供可靠性"这一思想带进后面的文件系统章节——第 42 章的日志、第 45 章的数据完整性都会再次遇到"一致更新"和"故障模型"的问题。
2核心概念速览
透明性(transparency)
对外 RAID 就是一块普通磁盘:一个线性块数组。操作系统和应用一行代码都不用改。
映射问题(mapping)
给定逻辑块号,RAID 要算出去哪块盘、哪个偏移,并发出一个或多个物理 I/O。
fail-stop 故障模型
磁盘要么完全正常,要么整块坏掉,而且坏了能立刻被发现。先不考虑静默损坏。
RAID-0 条带化
把块轮流分到各盘,性能和容量的上限,但没有任何冗余:坏一块盘就丢数据。
RAID-1 镜像
每个块存两份。可靠、随机读快,但容量减半,每次写都要写两份。
RAID-4 奇偶校验
每个条带加一个 XOR 校验块,只花一块盘的容量就能容忍一块盘故障;但小写要"读-改-写"。
小写问题(small-write problem)
RAID-4 每次小写都要读写校验盘,校验盘成为瓶颈,随机写只有 R/2。
RAID-5 旋转校验
把校验块轮流放在各盘上,消除单一校验盘瓶颈,随机写提升到 N·R/4。
3接口、内部结构与故障模型
在文件系统看来,RAID 就是一块又大又快(但愿如此)又可靠(但愿如此)的磁盘:一个线性的块数组,每块可读可写。文件系统发出逻辑 I/O 后,RAID 在内部计算该访问哪些盘,再发出一个或多个物理 I/O。例如镜像 RAID 每收到一次逻辑写,就要发出两次物理写。
给系统加新功能时,要想想能不能透明地加上,不要求系统其他部分做任何改变。RAID 就是完美的例子:管理员把 SCSI 磁盘换成 SCSI 接口的 RAID,主机、操作系统都一点不用改。解决了部署问题,RAID 从第一天起就更容易成功。
故障模型(fault model):要讨论"可靠",先要说清楚会发生什么故障。本章采用最简单的 fail-stop 模型:磁盘只有两种状态——正常(所有块都能读写)或故障(永久丢失)。并且故障很容易被检测到:RAID 控制器能立刻发现某块盘坏了。暂时不考虑更复杂的"静默"故障,比如磁盘内容损坏、某个扇区读不出来(潜在扇区错误,latent sector error)——这些留到第 45 章。
4怎样评估一个 RAID
三个维度:
- 容量(capacity):N 块盘、每块 B 个块,客户能用多少?没有冗余是 N·B;每块存两份(镜像)是 N·B/2;基于校验的方案介于两者之间。
- 可靠性(reliability):能容忍几块盘故障?(按 fail-stop 模型,只考虑整盘故障。)
- 性能(performance):很依赖负载。我们看两个指标——单请求延迟(一次逻辑 I/O 内部有多少并行)和稳态吞吐量(大量并发请求时的总带宽,本章重点)。
负载分两类:顺序(大块连续访问,如读 1MB,从块 x 到 x+1MB)和随机(每次一个小请求,如 4KB,地址随机,如数据库事务)。第 37 章告诉我们,一块盘在两种负载下差别巨大,所以设一块盘的顺序带宽为 S MB/s、随机带宽为 R MB/s,通常 S ≫ R。原书的例子:
| 参数 | 值 | 顺序:每次 10MB | 随机:每次 10KB |
|---|---|---|---|
| 平均寻道 | 7 ms | 7 ms | 7 ms |
| 平均旋转延迟 | 3 ms | 3 ms | 3 ms |
| 传输速率 | 50 MB/s | 10MB / 50MB/s = 200 ms | 10KB / 50MB/s = 0.195 ms |
| 一次请求总时间 | 210 ms | 10.195 ms | |
| 带宽 | S = 10MB / 210ms = 47.62 MB/s | R = 10KB / 10.195ms = 0.981 MB/s | |
顺序访问时寻道和旋转被大块传输"摊薄",S 接近磁盘峰值;随机访问几乎全在寻道和旋转,R 不到 1MB/s,S/R 接近 50。(原书把 KB/ms 近似记作 MB/s。)后面分析各级 RAID 时,都用 N、S、R 来表示吞吐量。
5RAID-0:条带化
RAID-0 严格来说不算 RAID——它没有冗余。但作为性能和容量的上限,它值得先弄懂。最简单的条带化(striping)把块轮流(round-robin)分到各块盘上。同一行的块叫一个条带(stripe):块 0、1、2、3 就在同一个条带里。这样做是为了在访问连续的大块数据时,尽量让所有盘并行工作。
每块盘上连续放几个块再换下一块盘,这个量叫 chunk 大小。原书 Figure 38.1 是 chunk = 1 块(4KB),Figure 38.2 是 chunk = 2 块(8KB),此时一个条带是 4 × 8KB = 32KB。拖动下面的参数看布局怎么变,输入逻辑块号看它被映射到哪里:
给定逻辑块 A,RAID 怎么知道去哪块盘、哪个偏移?chunk = 1 时只要两个整数运算:
Disk = A % number_of_disks
Offset = A / number_of_disks // 整数除法,4 / 3 = 1
原书的例子:4 块盘,请求块 14 → 盘 14 % 4 = 2,偏移 14 / 4 = 3,即第三块盘(从 0 数是盘 2)的第四个块(偏移 3)。原书留了个练习:"改一改公式支持别的 chunk 大小"。答案是先算 A 在第几个 chunk,再算 chunk 内的位置:
chunk = A / C // 第几个 chunk
Disk = chunk % N
Offset = (chunk / N) * C + A % C // 前面完整的行数 × C + chunk 内偏移
例如 N=4、C=2 时块 14:chunk = 7,盘 7 % 4 = 3,偏移 (7/4)×2 + 0 = 2——对照上面 Figure 38.2 验证一下。
chunk 大小的权衡
- 小 chunk:一个文件被切到很多盘上,单个文件的读写并行度高;但一个请求的定位时间取决于所有参与盘里最慢的那个,跨的盘越多,最大定位时间越大。
- 大 chunk:单文件内部的并行度低,要靠多个并发请求才能跑满吞吐;但定位时间短——如果一个文件完整落在一个 chunk 里,就只付一块盘的定位时间。
"最好"的 chunk 大小取决于负载,很难确定。实际阵列常用较大的 chunk(如 64KB),但本章分析里 chunk 大小不影响结论,所以下面都假设 chunk = 1 块。
RAID-0 分析
- 容量:完美,N·B。
- 可靠性:也"完美"——完美地糟糕:任何一块盘坏了,数据就丢了。
- 延迟:单块请求只是被转发给某一块盘,延迟和单盘一样。
- 吞吐量:顺序 N·S,随机 N·R——所有盘都在并行干活,这是其他级别的上限。
6RAID-1:镜像
镜像(mirroring):每个块存不止一份,每份放在不同的盘上,于是能容忍磁盘故障。典型做法是每个逻辑块两份物理副本(原书 Figure 38.3):盘 0 和盘 1 内容完全相同,盘 2 和盘 3 相同,数据在这两对镜像之间再条带化。
读时 RAID 有选择:可以读任意一份副本。例如读逻辑块 5,可以去盘 2 也可以去盘 3。写时没有选择:两份都必须更新才能保持可靠性——不过这两次写可以并行,比如写块 5 可以同时发给盘 2 和盘 3。
任何一次逻辑操作要改多块盘的 RAID 都会遇到一致更新问题(consistent-update problem)。以镜像为例:RAID 决定把某块写到盘 0 和盘 1,先给盘 0 发了写请求,还没来得及给盘 1 发,断电了。结果盘 0 是新版本、盘 1 是旧版本——两份副本不一致。我们希望两块盘的状态原子地改变:要么都是新的,要么都是旧的。
通用解法是某种预写日志(write-ahead log):先记下"我要用这些数据更新这两块盘",再去做。崩溃后运行恢复程序重放所有未完成的事务,就能保证镜像不会不同步。每次写都往磁盘上记日志代价太高,所以大多数 RAID 硬件带一小块非易失内存(NVRAM,如电池供电的 RAM)来记日志,这样既一致又不贵。第 42 章的文件系统日志会把这个思想发扬光大。
RAID-1 分析
- 容量:昂贵,镜像级别为 2 时只有 N·B/2。
- 可靠性:一定能容忍任意一块盘故障;运气好能容忍更多——在上图中盘 0 和盘 2 同时坏了也不丢数据,最多可容忍 N/2 块。但实践中不愿靠运气,一般认为镜像能处理单盘故障。
- 延迟:读和单盘相同;写要等两个并行的物理写都完成,承受两者中更差的寻道和旋转,平均比单盘略高。
- 顺序写:每次逻辑写变成两次物理写,最大带宽 (N/2)·S,峰值的一半。
- 顺序读:也只有 (N/2)·S!见下图。
- 随机读:最好的情况,把读分散到所有盘上,N·R。
- 随机写:(N/2)·R——每次逻辑写两次物理写,所有盘都在忙,但客户只感受到一半带宽。
7RAID-4:用奇偶校验省空间
镜像太费空间。基于奇偶校验(parity)的方法用更少的容量换取冗余,代价是性能。原书 Figure 38.4 是一个 5 盘 RAID-4:每个条带加一个校验块,比如 P1 由块 4、5、6、7 算出。
用什么函数算校验?需要它能在条带丢失任意一块时把那块算回来。XOR(异或)正好可以:一组比特中 1 的个数为偶数时 XOR 为 0,为奇数时为 1。
| C0 | C1 | C2 | C3 | P |
|---|---|---|---|---|
| 0 | 0 | 1 | 1 | XOR(0,0,1,1) = 0 |
| 0 | 1 | 0 | 0 | XOR(0,1,0,0) = 1 |
好记的说法:每一行(包括校验位)里 1 的个数必须是偶数——这是 RAID 为保证校验正确必须维护的不变量。恢复也就很自然:假设 C2 那一列丢了,第一行读出其余的 0(C0)、0(C1)、1(C3)、0(P),1 的个数是奇数,所以丢失的必定是 1。重建值的算法和算校验一模一样:把剩下的所有块(含校验)XOR 起来。
块是 4KB 不是 1 比特怎么办?逐比特做 XOR,结果放进校验块对应的比特位。原书用 2 比特的"块"举例:Block0..3 = 00 10 11 10 → Parity = 11;10 01 00 01 → 10。在下面自己试:点比特翻转,选一块"丢失",看 XOR 怎样把它算回来。
RAID-4 分析
- 容量:每组盘用 1 块盘存校验,(N−1)·B。
- 可靠性:容忍 1 块盘故障,不能更多——丢两块就没法重建了。
- 顺序读:除校验盘外的所有盘,(N−1)·S。
- 顺序写:用全条带写(full-stripe write)——例如块 0、1、2、3 一起写来(Figure 38.5),直接算出新 P0,然后 5 块盘(含校验)并行写。这是 RAID-4 写盘最高效的方式,带宽 (N−1)·S;校验盘虽然一直在忙,但不给客户增加带宽。
- 随机读:分散在数据盘上,(N−1)·R。
- 随机写:最有意思,见下。
小写:加法校验 vs 减法校验
假设要覆盖写块 1。直接写的话 P0 就不对了,必须同时更新 P0。两种方法:
- 加法校验(additive parity):并行读入条带里其他所有数据块(块 0、2、3),和新的块 1 XOR,得到新校验;再并行写新数据和新校验。问题是读的次数随盘数增长,大阵列要读很多块。
- 减法校验(subtractive parity):只读旧数据 Cold 和旧校验 Pold。新旧数据相同则校验不变;不同则把旧校验对应位翻转。用 XOR 一句话写完:
P_new = (C_old ⊕ C_new) ⊕ P_old (38.1)
以一个比特为例:原来 C2 = 1、P = 0,要写 C2new = 0:(1 ⊕ 0) ⊕ 0 = 1,校验翻转;若写 C2new = 1:(1 ⊕ 1) ⊕ 0 = 0,不变。对块来说就是 4096 × 8 个比特一起算,一般新旧块总会有不同,所以新校验块也会变。
原书的思考题:盘数多少时加法比减法 I/O 更少?拖动下面的参数自己算:
下面的分析都假设用减法:每次小写 4 次物理 I/O(2 读 2 写)。现在有大量写同时到来,RAID-4 能并行几个?看原书 Figure 38.6:同时写块 4 和块 13(标 *),它们分别在盘 0 和盘 1,数据的读写可以并行;但两者都要读写各自的校验块 P1 和 P3(标 +),而它们都在盘 4 上。
| 盘 0 | 盘 1 | 盘 2 | 盘 3 | 盘 4 | |
|---|---|---|---|---|---|
| 0 | 0 | 1 | 2 | 3 | P0 |
| 1 | *4 | 5 | 6 | 7 | +P1 |
| 2 | 8 | 9 | 10 | 11 | P2 |
| 3 | 12 | *13 | 14 | 15 | +P3 |
原书 Figure 38.6:写 4 和 13 时,数据盘 0、1 可并行,但两个请求都要读写盘 4
这就是基于校验的 RAID 的小写问题(small-write problem):数据盘本可并行访问,校验盘却让所有写串行化。校验盘每次逻辑写要做 2 次 I/O(读一次、写一次),所以 RAID-4 的随机小写吞吐量只有 R/2 MB/s——而且加盘也不会变好。
延迟:单次读映射到单盘,延迟同单盘;单次写要两读(并行)再两写(并行),总延迟约为单盘的两倍(读要等两个里较慢的;写回时磁头已就位,不需要寻道,可能比平均快些)。
8RAID-5:旋转校验
为了(部分地)解决小写问题,Patterson、Gibson 和 Katz 提出了 RAID-5:和 RAID-4 几乎一样,只是把校验块轮流放在各块盘上(原书 Figure 38.7),消除单一校验盘的瓶颈。
原书 Figure 38.7:5 盘 RAID-5(左对称布局)。每个条带的校验向左移一块盘,数据从校验盘右边开始排
- 与 RAID-4 相同:容量 (N−1)·B、容忍 1 块盘故障、顺序读写 (N−1)·S、单请求延迟(读 T,写 2T)。
- 随机读略好:所有盘都能用上,N·R。
- 随机写明显变好:请求之间可以并行了。例如写块 1 和写块 10:前者访问盘 1(数据)和盘 4(P0),后者访问盘 0(数据)和盘 2(P2),互不冲突。大量随机请求下所有盘大致均匀地忙,总带宽 (N/4)·R——4 倍的损失来自每次写仍然要 4 次 I/O,这是基于校验的 RAID 的固有代价。
因为 RAID-5 除了少数更好的地方外与 RAID-4 相同,它几乎完全取代了 RAID-4。唯一例外是明确知道只会做大块写、根本不会有小写的系统(如 NetApp 的 WAFL),那里用 RAID-4 更简单一些。
布局的细节:raid.py 支持两种 RAID-5 布局。左对称(left-symmetric)就是 Figure 38.7:第 r 个条带的校验在盘 N−1−(r mod N),数据从校验盘右边一块开始、绕回排列,这样顺序读时连续的块依次落在所有盘上。左非对称(left-asymmetric)的校验位置相同,但数据按盘号从小到大排、跳过校验盘(第二行是 4 5 6 P1 7)。在下面的模拟器里切换两者对比。
9模拟器:仿 raid.py 看每个逻辑请求变成哪些物理 I/O
这个模拟器重现了原书作业工具 raid.py 的核心:选 RAID 级别、盘数、chunk 大小,输入一串逻辑请求,逐步看每个请求被映射到哪块盘哪个偏移、产生哪些物理读写。每个块里存 1 字节的真实数据(十六进制小字),所以你能看到校验是怎样 XOR 出来的;还可以拔掉一块盘,看降级读如何用 XOR 重建数据,最后换盘重建。
RAID 映射与物理 I/O
r 14 读块 14;w 4 写块 4;w 0 4 从块 0 开始写 4 块;fail 2 拔掉盘 2;replace 换新盘并重建。蓝框 = 物理读,红框 = 物理写,黄框 = 逻辑目标。点任意格子做"反向映射"。建议的玩法:① 用"38.6 写 4、13"看 RAID-4 的校验盘(盘 4)负载条是怎样一枝独秀的,再把级别换成 RAID-5 重新载入同一序列;② 在 RAID-5 下把"小写校验"切成加法,比较同一个写请求的 I/O 数;③ 试 w 0 4(整条带)和 w 1 2(半条带)的区别;④ 运行"拔盘"预设,核对降级读算出的值是否等于原值。
10对比总结:Figure 38.8 计算器
把前面的分析汇总成一张表(原书 Figure 38.8)。这里省略了不少细节:镜像写时寻道时间是两次寻道的最大值,比单盘略高;RAID-4/5 更新校验时第一次读旧校验多半要完整寻道和旋转,但第二次写校验只需旋转。改下面的参数,表格里的数值会实时更新(绿色 = 该行最优):
RAID 容量、可靠性与性能对比
结论(原书原话的意思):
- 只要性能、不在乎可靠性:条带化(RAID-0)显然最好。
- 要随机 I/O 性能又要可靠性:镜像(RAID-1)最好,代价是容量。
- 容量和可靠性是主要目标:RAID-5 胜出,代价是小写性能。
- 总是做顺序 I/O、又想最大化容量:也选 RAID-5。
11其他有趣的 RAID 话题
- 原始分类里还有 RAID-2、RAID-3,以及能容忍多盘故障的 RAID-6(例如行-对角线校验,用两块盘的容量存两种校验)。
- 磁盘坏了怎么办?很多阵列有热备盘(hot spare)随时顶上。故障期间(降级模式)和重建期间的性能如何?在上面的模拟器里,降级读一个块要读 N−1 块盘,重建整块盘要读完其余所有盘——这段时间既慢又没有冗余。
- 更真实的故障模型:潜在扇区错误、块损坏,以及对应的检测与处理技术(第 45 章)。
- RAID 也可以做成软件层:软件 RAID 更便宜,但有自己的问题,包括前面说的一致更新问题(没有 NVRAM 可用)。
12先预测,再验证
r 9; r 16; r 23 验证。换成左非对称呢?看答案
每条带 4 个数据块。块 9:条带 2(偏移 2),条带内第 1 个;校验盘 = 4 − 2 = 2;左对称数据从盘 3 开始 → 块 8 在盘 3、块 9 在盘 4。块 16:条带 4,校验盘 0,块 16 在盘 1、偏移 4。块 23:条带 5,校验盘 4 − (5 mod 5) = 4,第 3 个 → 盘 3、偏移 5。
左非对称:块 9 → 数据按盘号跳过校验盘 2 排:8 在盘 0、9 在盘 1;块 16 → 盘 1(条带 4 校验在盘 0,第 0 个数据在盘 1);块 23 → 盘 3。
看答案
C=1:盘 2,偏移 3。C=2:chunk 7 → 盘 3,偏移 (7/4)·2 + 0 = 2。C=4:chunk 3 → 盘 3,偏移 0·4 + 2 = 2。chunk 越大,相邻的逻辑块越倾向于待在同一块盘上。
读 盘1 偏移2、读 盘4 偏移2、写 盘1 偏移2、写 盘4 偏移2。逻辑请求是什么?看答案
两读两写、且涉及校验盘 4 → 这是一次减法小写。数据在盘 1 偏移 2 → 条带 2 的第 1 个数据块 → 逻辑块 2·4 + 1 = 9,即 w 9。
w 0 1、w 0 2、w 0 3、w 0 4 分别产生多少次物理 I/O(减法)?什么请求大小对 RAID-4/5 最高效?看答案
1 块:4 次(2 读 2 写)。2 块:6 次(读 2 块旧数据 + 旧校验,写回 3 块;加法只要 5 次)。3 块:8 次(加法仍只要 5 次——"自动取少"模式会选它)。加法恒为 N 次,所以写的块越多越划算。4 块:整条带写,5 次写、0 次读。所以应该按完整条带的整数倍写(这里是 4 块 = 16KB),并且对齐条带边界。
看答案
RAID-0:100 次 I/O 平摊到 4 盘 ≈ 25T。RAID-1:200 次物理写 / 4 ≈ 50T。RAID-4:数据盘各 ~67 次,但校验盘要做全部 200 次 ≈ 200T(R/2 的由来)。RAID-5:400 次 I/O 平摊到 4 盘 ≈ 100T(N·R/4 的由来)。随机抽样会有波动,但量级一致。读请求呢?RAID-0 与 RAID-1 都 ≈ 25T,RAID-4 ≈ 33T(校验盘闲着),RAID-5 ≈ 25T。
13动手实验
用 C 在内存里模拟 N 块盘,实现 Figure 38.7 同款的左对称 RAID-5:全条带写填满阵列 → 拔掉磁盘 2 → 逐块 XOR 重建并与原数据比对 → 对 1000 次随机小写分别用加法和减法更新校验,比较 I/O 次数、确认两种方法得到的校验块一致。
cd labs/38-raid && make && ./raid
也可以 ./raid 3 512 改盘数和块大小。示例输出(你的机器上数字会相同,因为这是确定性的计算;不同参数会不同):
== RAID-5(左对称),5 块盘,每块 4096 字节,每盘 64 块,可用 256 个逻辑块 ==
前 3 行布局(与原书 Figure 38.7 相同的规则):
0 1 2 3 P0
5 6 7 P1 4
10 11 P2 8 9
[1] 全条带写填满阵列:0 次读,320 次写(每行 5 写、0 读)
[2] 磁盘 2 故障 → 重建它的 64 个块(51 个数据块 + 13 个校验块):64/64 与原数据完全一致,共 256 次读
例:第 0 行第 0 字节:0xA2 ⊕ 0x68 ⊕ 0xF5 ⊕ 0x10 = 0x2F(盘 2 上原本是 0x2F)
[3] 1000 次随机单块小写:加法 vs 减法(N 从 3 到 8)
N | 加法 I/O/次 | 减法 I/O/次 | 两种方法的校验块是否相同 | 更省的方法
3 | 3.0 | 4.0 | 相同 ✓ | 加法
4 | 4.0 | 4.0 | 相同 ✓ | 一样多
5 | 5.0 | 4.0 | 相同 ✓ | 减法
6 | 6.0 | 4.0 | 相同 ✓ | 减法
7 | 7.0 | 4.0 | 相同 ✓ | 减法
8 | 8.0 | 4.0 | 相同 ✓ | 减法
该观察到:重建的 64 个块全部与原数据一致;每重建一个块要读 N−1 块盘;加法每次 N 次 I/O、减法固定 4 次,N=4 是交叉点。两种方法算出的校验完全相同——XOR 满足交换律、结合律,且 x ⊕ x = 0,所以 Cold ⊕ Cnew 恰好"标出了"哪些位需要翻转。
14自测题
15常见误区与小结
- "RAID 就是备份"——不是。RAID 只防整盘故障;误删文件、软件 bug、病毒写坏数据,会被忠实地镜像 / 更新校验到所有盘上。
- "RAID-0 的 0 表示零风险"——恰恰相反,它没有任何冗余,N 块盘里任意一块坏都会丢数据,盘越多越危险。
- "镜像读可以拿到 N·S"——朴素的顺序读只有 (N/2)·S;随机读才是 N·R。
- "加盘能提高 RAID-4 的随机写"——不能,校验盘瓶颈让它固定在 R/2。
- "减法校验总比加法好"——N=3 时加法 3 次 I/O 比减法 4 次少;N=4 时相等。
- "坏盘后阵列照常工作,不急"——降级模式下读慢、而且已无冗余,再坏一块就全丢了;应尽快用热备盘重建。
本章要点
- RAID 把多块独立的盘透明地变成一个更大、更快、更可靠的"盘";映射问题用简单的整数运算解决。
- RAID-0:容量 N·B、无冗余、性能上限。RAID-1:容量减半,可靠,随机读好;写要两份。
- XOR 校验以一块盘的容量换取单盘容错:丢了哪块,就把其余的全部 XOR 起来。
- 全条带写最有效;小写需要读-改-写(加法 N 次或减法 4 次 I/O)。RAID-4 的校验盘是瓶颈(R/2),RAID-5 旋转校验改善到 N·R/4。
- 选哪种 RAID、chunk 设多大,取决于负载——与其说是科学,不如说是艺术。
和后续章节的联系:从下一章开始我们回到"一块盘"的视角,学习文件系统的 API(第 39 章)和实现(第 40 章)。RAID 里的一致更新问题会在第 42 章以"崩溃一致性"的形式卷土重来,日志(journaling)正是 RAID 用 NVRAM 记日志这一思想的推广;而 fail-stop 之外的静默错误,则留给第 45 章的校验和与数据完整性。