1. 存储层次
1.1 金字塔结构
寄存器 <1ns ~KB
L1/L2/L3 1~40ns ~MB
DRAM 50~100ns ~GB
SSD 10~100μs ~TB
HDD 5~15ms ~TB
磁带 秒级 ~PB
越往下容量越大、速度越慢、单位成本越低。存储系统的核心任务就是用层次结构把热数据放在上层。
1.2 局部性原理
- 时间局部性:刚访问的数据很可能再次被访问 → 缓存。
- 空间局部性:相邻数据很可能被一起访问 → 预读、块传输。
所有存储优化(缓存、预读、条带化)都建立在局部性之上。
1.3 关键指标
- 吞吐量(bandwidth):每秒传多少 MB。
- IOPS:每秒多少次 I/O 操作。
- 延迟(latency):单次请求往返时间。
顺序 I/O 与随机 I/O 差距巨大:HDD 上随机比顺序慢百倍,SSD 上差距缩到 10 倍以内。
2. HDD 与 SSD 特性
2.1 机械硬盘的延迟构成
一次随机读的耗时:
总延迟 = 寻道时间 + 旋转延迟 + 传输时间
≈ 8ms + 4ms(7200rpm 半圈) + 忽略
- 寻道时间:磁头移动到目标磁道,是最大头。
- 旋转延迟:等目标扇区转到磁头下,平均半圈。
- 7200 RPM 转一圈 8.3ms,平均旋转延迟约 4.2ms。
结论:HDD 的瓶颈是机械动作,优化方向是减少寻道(顺序化、合并、预读)。
2.2 磁盘几何与寻址
- 磁道(track)→ 柱面(cylinder)→ 扇区(sector)。
- 传统扇区 512 字节,现代为 4KB(4Kn / 512e)。
- 512e(512 模拟):物理 4K、逻辑报 512,写入未对齐会触发读改写(RMW)。
2.3 SSD 的内部结构
SSD 由**闪存颗粒 + 主控(controller)**组成:
- 页(page):读写的最小单位,常见 4KB~16KB。
- 块(block):擦除的最小单位,常见 256KB~几 MB。
- FTL(Flash Translation Layer):把逻辑地址映射到物理页,是 SSD 的核心固件。
关键约束:闪存只能按页写、按块擦。改一个页要先擦整个块,于是产生写放大。
2.4 写放大与磨损均衡
写放大(WA) = 实际写入闪存的量 / 主机请求写入量。
- 垃圾回收(GC):块内有效页搬走、整块擦除,搬迁过程产生额外写入。
- TRIM:告诉 SSD 哪些块已删除,减少 GC 搬迁量。
- 磨损均衡(wear leveling):动态与静态两种,把擦写均匀分散到所有块,避免个别块先坏。
fstrim -av # 手动 TRIM
cat /sys/block/nvme0n1/queue/discard_max_bytes
smartctl -a /dev/nvme0n1 # 查看磨损与健康
2.5 写放大与过度配置
企业级 SSD 通过 OP(over-provisioning,过度配置) 预留 7%~28% 空间给 GC,降低写放大、提升寿命与随机写性能。
3. RAID 基础概念
3.1 RAID 是什么
RAID(独立磁盘冗余阵列) 把多块磁盘组合成一块逻辑盘,目标是提升性能、容量或可靠性。注意它不是备份——它防的是磁盘故障,不防误删、勒索、机房事故。
3.2 三个基本技术
- 条带化(striping):数据切块分散到多盘,提升吞吐。
- 镜像(mirroring):数据写多份,提升可靠性。
- 奇偶校验(parity):用 XOR 冗余,省空间地容错。
3.3 关键术语
| 术语 | 含义 |
|---|---|
| 条带(stripe) | 跨盘的一组数据块 |
| 条带单元(chunk) | 单盘上的一块 |
| 条带宽度 | 参与条带的盘数 |
| 条带大小 | 单个 chunk 的大小,常见 64K~1M |
4. RAID 0 与 RAID 1
4.1 RAID 0 条带化
数据交替写入各盘,无冗余。
Disk0: A1 A3 A5 ...
Disk1: A2 A4 A6 ...
- 容量:100% 可用(N 盘即 N 倍)。
- 性能:读写吞吐近似 N 倍,IOPS 也近 N 倍。
- 可靠性:任意一盘的故障即全盘数据丢失,MTTF 反而降到单盘的 1/N。
RAID 0 只适合可重建的临时数据(缓存、渲染中间结果)。
4.2 RAID 1 镜像
数据完整写两份:
Disk0: A1 A2 A3 ...
Disk1: A1 A2 A3 ...(完全副本)
- 容量:50%(N 盘可用 N/2)。
- 读性能:可并行读多份,读吞吐近 N 倍。
- 写性能:受最慢盘限制,约等于单盘。
- 可靠性:可容忍 N/2 盘故障(且需故障分散在不同镜像对)。
RAID 1 适合系统盘、数据库日志盘等写少读多且要求低延迟的场景。
4.3 RAID 1 的读策略
读时可从任一副本读,控制器做负载均衡;若某盘寻道繁忙,可从另一盘读,提升随机读 IOPS。
5. RAID 5 与 RAID 6
5.1 RAID 5 单校验
数据与校验交替分布在所有盘上,校验块轮转:
Disk0: A1 A2 A3 P4
Disk1: A2 A3 P4 A1
Disk2: A3 P4 A1 A2
Disk3: P4 A1 A2 A3
校验用 XOR:P = A1 ⊕ A2 ⊕ A3。任一块可由其余块 XOR 还原。
- 容量:
(N-1)/N,N=4 时 75%。 - 容错:仅容 1 盘故障。
- 写性能:每次写要更新校验,产生读改写(见写惩罚)。
5.2 RAID 6 双校验
用两种独立校验(P 用 XOR,Q 用伽罗华域乘法),可容 2 盘同时故障:
P = A1 ⊕ A2 ⊕ A3
Q = g1·A1 ⊕ g2·A2 ⊕ g3·A3 (GF(2^8) 上的乘加)
- 容量:
(N-2)/N。 - 容错:2 盘。大容量阵列(>8 盘)的必备,因为重建期间第二盘故障概率不低。
5.3 校验重建
替换故障盘后,控制器读其余盘对应块 XOR 出丢失数据。重建期间阵列降级运行,性能下降且再坏一盘即全毁——这就是重建窗口风险。
6. RAID 10 与组合级别
6.1 RAID 10
先镜像再条带(RAID 1+0):
Mirror Pair 0: Disk0 = Disk1
Mirror Pair 1: Disk2 = Disk3
↑ 两组之间做条带
- 容量:50%。
- 性能:读写均好,随机 IOPS 高。
- 容错:每组镜像可坏一盘,容错能力取决于坏盘分布。
- 重建快:只从镜像副本拷贝,无需读全阵列算校验,重建窗口远短于 RAID 5。
RAID 10 是数据库与高 IOPS 场景的首选,代价是 50% 容量。
6.2 RAID 01 与 RAID 10 的差别
RAID 01 是先条带再镜像。RAID 01 在特定坏盘组合下会整组失效(如两条带各坏一盘且落在同一镜像对),容错能力不如 RAID 10,因此生产环境一律用 RAID 10。
6.3 其他组合
- RAID 50:条带 + RAID 5,兼顾容量与性能。
- RAID 60:条带 + RAID 6,大容量高可靠。
- JBOD:只是把盘串成一个大盘,无冗余无条带。
7. 写惩罚与写洞
7.1 RAID 5 写惩罚
修改一个小块需要:
① 读旧数据 D_old
② 读旧校验 P_old
③ 算新校验 P_new = P_old ⊕ D_old ⊕ D_new
④ 写新数据
⑤ 写新校验
一次逻辑写变成 2 读 2 写,即 写惩罚 = 4(RAID 6 为 6)。所以 RAID 5 的随机写 IOPS 约等于单盘 IOPS / 4。
对策:用全条带写(full-stripe write)——一次写满整个条带时,校验可由数据直接算出,无需读旧值,惩罚降为 1。
7.2 写洞(write hole)
断电时数据块与校验块可能不一致:数据已写、校验未写(或反之),此时若另一盘故障,重建出的数据是错的,且无法检测。这就是写洞。
对策:
- UPS / 掉电保护:最简单有效。
- 日志式 RAID(journaling):写数据前先把意图写日志,崩溃后重放。
- 写意图位图(write-intent bitmap):只记录哪些区域待同步,重建时优先重算这些区域。
7.3 写惩罚与业务选型
| 级别 | 随机写惩罚 | 适用负载 |
|---|---|---|
| RAID 0 | 1 | 临时数据 |
| RAID 1/10 | 1 | 随机写密集(数据库) |
| RAID 5 | 4 | 顺序读多、写少 |
| RAID 6 | 6 | 大容量归档 |
8. 可靠性建模
8.1 MTBF 与 AFR
- MTBF(平均无故障时间):厂商标称值,消费盘约 50 万~100 万小时,企业盘 200 万小时。
- AFR(年化故障率):
AFR ≈ 8760 / MTBF。MTBF 100 万小时对应约 0.88%/年。
8.2 阵列故障率
N 盘 RAID 0 的 MTTF 降到单盘的 1/N。盘越多,阵列越脆弱——这是 RAID 5 在大容量阵列中失宠的根本原因。
8.3 重建窗口风险
重建一块 4TB 盘可能耗时 数小时到十几小时(受负载影响)。期间:
P(重建期间再坏一盘) ≈ AFR × 重建时长 / 年小时数
以 AFR 2%、重建 10 小时估算,单盘再坏概率约 0.023%;但若阵列有 12 盘,且重建要读所有盘(RAID 5),任一盘在窗口内故障即全毁,风险放大 11 倍。这就是 RAID 6 存在的理由。
8.4 为什么 RAID 不是备份
- 不防误删、误格式化:删除会同步到所有盘。
- 不防勒索软件:加密同样同步。
- 不防控制器故障、机房灾难:需要异地副本。
- 不防静默数据损坏:位翻转需校验和(如 ZFS 的 checksum)才能发现。
9. 条带化与对齐
9.1 4K 对齐
现代磁盘物理扇区 4KB。若分区起始未按 4KB 对齐,一个逻辑写会跨两个物理扇区,触发读改写,性能腰斩。
parted /dev/sda unit s print # 检查起始扇区是否为 8 的倍数
parted -a optimal /dev/sda mkpart primary 0% 100% # 自动对齐
9.2 条带大小选择
- 小条带(16K~64K):适合大量小文件、随机读,负载分散到多盘。
- 大条带(256K~1M):适合大文件顺序读写,减少跨盘次数。
条带大小应与文件系统块大小、业务 IO 大小匹配,错配会浪费带宽。
9.3 条带与文件系统的配合
文件系统块、RAID chunk、磁盘扇区三层若不对齐,每次 IO 都会跨边界。创建阵列时显式指定 chunk size,创建文件系统时指定 stride/stripe-width。
mdadm --create /dev/md0 --level=5 --raid-devices=4 \
--chunk=64 /dev/sd[b-e]
mkfs.ext4 -E stride=16,stripe-width=48 /dev/md0
10. 存储栈与文件系统
10.1 Linux 存储栈
应用(read/write)
→ VFS(虚拟文件系统)
→ 具体文件系统(ext4/XFS/btrfs)
→ 页缓存(Page Cache)
→ 块层(Block Layer)+ IO 调度器
→ 设备驱动
→ 物理设备
10.2 页缓存
读:命中页缓存直接返回,未命中触发预读。
写:默认回写(write-back),先进页缓存标记脏页,由内核回刷线程异步落盘。
echo 3 > /proc/sys/vm/drop_caches # 清页缓存(测试用)
vmstat 1 # 观察 bi/bo 与缓存
风险:write-back 下断电会丢未回刷的脏页,数据库需 fsync 保证持久。
10.3 IO 调度器
| 调度器 | 特点 |
|---|---|
| none / noop | 不排序,适合 SSD、NVMe |
| mq-deadline | 多队列 + 截止时间,通用 |
| BFQ | 按进程公平分配带宽,桌面友好 |
SSD 无需寻道优化,用 none 或 mq-deadline;HDD 用 mq-deadline 合并相邻请求。
10.4 写屏障与 FUA
fsync 触发 FLUSH 缓存刷新,确保数据真正落盘。文件系统的 journal(日志)保证元数据一致性,但数据一致性仍需 fsync。
11. 分布式存储的副本与纠删码
11.1 三副本
把每个数据块存 3 份到不同节点/机架:
- 优点:读可并行、重建快(拷一份即可)、实现简单。
- 缺点:存储开销 200%(3 份存 1 份数据)。
11.2 纠删码 EC
把数据切成 k 块,算出 m 块校验,共 k+m 块分布到不同节点:
k=10, m=4 → 可容 4 块丢失,存储开销 40%
- 优点:存储效率远高于三副本,适合冷数据、归档。
- 缺点:重建需读 k 块并解码,CPU 与网络开销大、重建慢;小文件场景不划算(需补齐块)。
11.3 副本与纠删码的取舍
| 维度 | 三副本 | 纠删码 |
|---|---|---|
| 存储开销 | 200% | 40%~100% |
| 重建成本 | 低 | 高 |
| 读延迟 | 低 | 需解码 |
| 适用 | 热数据、低延迟 | 冷数据、大文件 |
主流做法是分层:热数据三副本,冷数据转 EC,兼顾性能与成本。
12. SSD 时代的 RAID 取舍
12.1 传统 RAID 卡的问题
硬件 RAID 卡为 HDD 设计,对 SSD 有三大问题:
- 写放大叠加:RAID 5 的读改写 + SSD 内部 GC,放大成倍。
- 重建慢:重建要读全阵列,SSD 虽快但卡本身成瓶颈。
- TRIM 透传:部分卡不支持 TRIM 透传给 SSD,加速磨损。
12.2 软 RAID 与 ZFS
- mdadm:Linux 软件 RAID,灵活、无硬件依赖,性能已接近硬卡。
- ZFS:文件系统与卷管理合一,端到端校验和防静默损坏,RAID-Z 系列用变宽条带 + 校验,无写洞(写时复制)。
- btrfs:类似 ZFS,支持校验和与 RAID 1/10/5/6(5/6 稳定性曾受质疑)。
12.3 NVMe 时代的现实选择
- 性能优先:RAID 10,重建快、无写惩罚,NVMe 的高 IOPS 才发挥得出来。
- 容量优先 + 大阵列:RAID 6 或 RAID-Z2,容忍双盘故障。
- 纠删码:分布式场景(Ceph、MinIO)用 EC 池,替代传统 RAID。
- 单盘可靠性已很高:企业 NVMe 的 AFR 低,很多场景直接用副本或 EC 而非 RAID。
13. 常见陷阱
- 把 RAID 当备份:RAID 只防盘坏,误删、勒索、火灾照样全丢,必须有离线与异地备份。
- RAID 5 用在数据库:写惩罚 4 倍,随机写性能崩塌,数据库应上 RAID 10。
- 大阵列用 RAID 5:重建窗口内再坏一盘即全毁,超过 8 盘务必用 RAID 6。
- 分区未 4K 对齐:每次写触发读改写,性能腰斩,建分区时用
-a optimal。 - 条带大小与负载不匹配:小条带配大文件顺序读会频繁跨盘,大条带配随机写会热点集中。
- 忽略写洞:无掉电保护的 RAID 5/6 在崩溃后可能校验不一致,应配 UPS 或日志式 RAID。
- SSD 上开 RAID 5 且不传 TRIM:写放大叠加,寿命与性能双输。
- 用 SMART 只看温度:应关注重分配扇区数、待定扇区、磨损指示等关键属性。
- 以为重建是后台无感:重建期间阵列降级、性能下降,业务高峰重建风险高。
- 三副本存所有数据:冷数据也用三副本会浪费数倍成本,应按冷热分层。
参考文章
- 文件系统与 IO — 页缓存、块层与调度器的实现细节
- 操作系统体系结构 — 存储栈在操作系统中的位置
- 分布式系统基础 — 副本、一致性与故障模型
- 数据库原理 — WAL 与 fsync 在持久化中的角色
- 虚拟化与容器原理 — 虚拟磁盘与存储直通
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。