首页/系统/服务器硬件与 RAID 速查/校验计算入门:XOR 原理
RAID 级别与计算68 条

校验计算入门:XOR 原理

RAID 5 的校验就是异或(XOR):P = D1 ⊕ D2 ⊕ D3 ⊕ …,任意一块数据可由其余数据与 P 反推。理解异或就能理解为什么同一时刻只能坏一块盘。

校验就是异或

RAID 5 的校验来自异或(XOR)运算:P = D1 ⊕ D2 ⊕ D3……。异或有三个性质——同一个数异或两次回到原值、可交换、可结合——正是它们让校验能反推出任意一块数据:D1 = P ⊕ D2 ⊕ D3。理解这条式子,就能同时理解两件常被误解的事:为什么 RAID 5 同一时刻只能坏一块盘(未知数多于方程,方程组无解),以及为什么重建必须读遍其余所有盘(每个字节都要重新算一遍)。

基本信息

运算符号⊕ 表示按位异或(XOR),相同为 0、不同为 1
关键性质a ⊕ a = 0;a ⊕ 0 = a;满足交换律与结合律
重建公式任一数据块 = 校验块 ⊕ 其余所有数据块
RAID 6 的扩展再加一套基于伽罗瓦域乘法的 Q 校验,得到两个独立方程
开销来源重建时每恢复一个字节都要读其余所有盘的对应位置

4 盘 RAID 5 单条带示例(1 字节块)

4 盘 RAID 5 单条带示例(1 字节块)
D1 = 0x6A    D2 = 0x3F    D3 = 0x9C
P  = D1 ^ D2 ^ D3 = 0x49
校验一:D1 = P ^ D2 ^ D3(算出原值)
校验二:任意两块丢失 -> 只剩一条方程,两个未知数,无解

用 Python 验证

用 Python 验证
python3 -c "print(hex(0x6A ^ 0x3F ^ 0x9C))"          # 得 0x49,即校验值
python3 -c "print(hex(0x49 ^ 0x3F ^ 0x9C))"          # 反推 D1,得 0x6A
python3 -c "print(hex(0x6A ^ 0x6A))"                 # 自反性,得 0x0

从方程看容错上限

级别独立方程数可解未知数结论
RAID 51 个(P)1 块盘坏两块即无解
RAID 62 个(P 与 Q)2 块盘坏三块即无解
镜像(RAID 1/10)不靠方程,靠副本副本数量决定的容错容错深度等于副本冗余度

几个常见推论

  • 校验不是数据副本:它只是计算结果,不能单独当作数据来读
  • 重建要读遍其余所有盘:这就是重建慢且脆弱的根本原因
  • 多一组校验就多一条方程:这是 RAID 6 能容忍两块盘故障的数学解释
  • 校验块轮转分布:避免所有校验读写集中在一块盘上形成瓶颈
两块盘同时丢失时 XOR 无法求解(未知数多于方程),这就是 RAID 5 容错上限的数学原因;RAID 6 用两套独立方程(P 与 Q)把上限提高到两块盘。

易错点

  • 把校验当冗余数据副本:校验是计算结果,单靠校验块无法直接读出数据
  • 误以为 RAID 5 可逐盘恢复:恢复推理以其余所有盘为前提,盘数越多需要读取的数据越多
  • 以为多块校验只是「更保险」:RAID 6 的第二套校验是独立方程,代价是写惩罚升到 6
  • 忽略校验的开销来源:写一次数据往往要连带更新校验,这就是写惩罚的由来

数据来源与参考

  • 《The RAID Book》(XOR 校验推导)
  • SNIA 存储术语表(parity)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌