10.7 纠删码与副本的取舍

一句话

副本用 “空间换简单”(3 份、读任意一份、修复只拷一份),纠删码用 “计算换空间”(1.4–1.5 份、重建要读 k 块、CPU 参与);选型只看两个数:存储成本与重建代价。

实测:几种方案的空间与重建代价

方案 空间开销 可容错 重建 1 块需读
3 副本 3.00× 2 块 1 份
EC 4+2 1.50× 2 块 4 块
EC 6+3 1.50× 3 块 6 块
EC 8+3 1.38× 3 块 8 块
EC 10+4 1.40× 4 块 10 块

例:1PB 原始数据 → 3 副本 3PB;EC 8+3 约 1.375PB(省 54%)。

空间开销 = (k + m) / k
重建读放大 ≈ k(修 1 块要读 k 块参与解码)
可容错 = m 块

三者的真实代价对比

维度 3 副本 纠删码
存储成本 3× 1.4–1.5×
读延迟 低(任一副本) 中(正常读也读多块/或从一块读)
重建网络 1 份 k 份
重建 CPU 无 有(解码)
小对象效率 差(3 倍空间) 更差(分块开销占比高)
适用 热数据、低延迟、小对象 温/冷数据、大对象、归档

代码:算一算 “该用哪个”

def cost(size_pb, k, m, price_per_tb_month=20, rebuild_gbps=1):
    overhead = (k + m) / k
    stored = size_pb * overhead
    monthly = stored * 1024 * price_per_tb_month
    rebuild_hours = (size_pb * 1024) / (rebuild_gbps * 3600) * k   # 重建读 k 份
    return dict(overhead=round(overhead, 2), stored_pb=round(stored, 2),
                monthly_usd=round(monthly), rebuild_hours=round(rebuild_hours, 1))

print("3 副本:", cost(1, 1, 2))   # 近似 3x
print("EC 8+3:", cost(1, 8, 3))

判据:热数据用副本(延迟与小对象友好),冷数据用 EC(空间省 50%+);重建带宽与 CPU 要单独评估,否则 “省下的存储费” 会被 “重建时间/业务影响” 吃掉。

反模式

反模式 后果
全部数据用 3 副本 存储成本 2–3 倍,账单难看
热数据用 EC 读放大 + 解码 CPU,延迟上升
小对象用 EC 分块与元数据开销占比过高
只看空间、不看重建 集群越大,重建越慢,故障窗口越长
重建不限速 重建流量挤占前台,业务抖动
不做过 “同时坏 2 块” 的演练 真坏 2 块时才发现恢复不了

三条铁律

🔑 热数据副本、冷数据 EC;按访问频率分层。

🔑 EC 的重建读放大 ≈ k,要按 RTO 反推 k 与带宽。

🔑 空间省下来的钱,要扣掉重建与 CPU 成本 再比较。

自检

Q1 为什么 EC 8+3 的空间开销是 1.375×,而不是 8/3?

▸ 答案:因为公式是 (k+m)/k:8 个数据块 + 3 个校验块 = 11 块存 8 块的数据,11/8 = 1.375。8/3 是 “每 3 个数据块配 1 个校验块” 的另一种配比(3+1),不是 8+3 的算法。

Q2 EC 的 “重建读放大 ≈ k” 意味着什么?

▸ 答案:意味着修 1 个块要读取 k 个块参与解码:k 越大,重建占用的网络与磁盘带宽越多,重建时间越长。所以 “k 大省空间” 的代价是 “重建更贵、故障窗口更长”。

Q3 为什么热数据不用 EC?

▸ 答案:因为 EC 在正常读时也可能要读多块并解码(取决于实现),带来读放大与 CPU 开销;而热数据对延迟敏感、访问频繁,3 副本 “读任意一份” 更简单更快。EC 的优势(省空间)在热数据上被 “延迟成本” 抵消。

Q4 小对象为什么不适合 EC?

▸ 答案:因为 EC 要把对象切成 k 块并生成 m 个校验块:对象越小,分块与元数据开销占比越高,甚至 “校验块比数据还大”。小对象通常用副本或 “打包成大对象再 EC”。

Q5 重建速度怎么估?

▸ 答案:重建时间 ≈ (数据量 × k) / 可用带宽:例如 1PB、EC 8+3、重建带宽 1Gbps,理论约 1PB×8 / 1Gbps ≈ 8×10^15×8/(1.25×10^8) 秒 量级(约数天)。所以大规模集群必须限速并规划 “故障窗口”。

Q6 3 副本真的能容 2 块故障吗?

▸ 答案:能,但仅在故障域独立时:3 副本分布在 3 个不同机架,坏 2 个机架仍剩 1 份;如果 3 份都在同一机架,坏 1 个机架就全丢(见 10.6 元数据管理与副本放置)。所以 “容错数” 必须和 “故障域” 一起说。

Q7 怎么决定 “哪些数据用 EC”?

▸ 答案:按 “访问频率 × 对象大小 × 延迟要求” 分层:热 + 小 + 低延迟 → 副本;温/冷 + 大 + 可容忍延迟 → EC;归档可以更激进(如 EC 10+4 + 更高压缩)。分层策略要写进生命周期规则,而不是靠人工判断。

关联