副本还是纠删码:冗余机制的取舍
三副本浪费 67% 空间,EC 省空间但重建时能把集群拖垮。这节课算清这笔账。
学完这节你能做到
- 计算任意副本数 / EC 方案的空间效率与故障容忍度
- 解释 EC 的读放大、写放大与重建代价
- 给出"什么场景用副本、什么场景用 EC"的判断依据
冗余是在花钱买"允许坏几个"
分布式存储的第一性问题是:盘一定会坏,机器一定会宕。既然如此,就必须存冗余信息。冗余方式有两大流派:
- 多副本:同一份数据存 N 份,简单粗暴
- 纠删码(EC):把数据切成 k 块,算出 m 块校验,任意 k 块就能还原
它们的差别不只是"省不省空间",而是在空间、性能、恢复代价、故障容忍度四个维度上的一组取舍。
多副本:算法最笨,运维最省心
3 副本的账很好算:
空间效率 = 1 / 3 = 33.3%
可容忍同时故障 = 2 份(按主机故障域时 = 2 台主机)
读:任意一副本都能读,天然的读扩展
写:必须写完全部 3 份才返回,写放大 3 倍
恢复:坏一块盘 → 从另外的副本直接拷贝,纯顺序读写
副本的最大优点在最后一行:恢复就是拷贝,不需要计算,也不需要读很多块盘。这让它在故障期间对集群的冲击最小。
2 副本的空间效率是 50%,看着很诱人。但它有个致命问题:坏一块盘后,数据只剩一份,此时进入重建窗口。重建一块 16TB 的盘按 200MB/s 算需要约 22 小时——在这 22 小时里,只要另一个副本所在的盘也坏了,数据就永久丢失。而且 2 副本在出现不一致时无法投票判定谁对。生产环境请用 3 副本或 EC。
纠删码:省空间,但把代价转移到了 I/O 上
EC 用 k + m 表示:k 个数据块,m 个校验块。
空间效率 = k / (k + m)
可容忍同时故障 = m 个
常见方案的效率对比:
| 方案 | 空间效率 | 容忍故障 | 最少节点(主机故障域) | 典型用途 |
|---|---|---|---|---|
| 3 副本 | 33.3% | 2 | 3 | 块存储、元数据池 |
| EC 4+2 | 66.7% | 2 | 7 | 中小集群对象存储 |
| EC 8+3 | 72.7% | 3 | 12 | 大集群,容错优先 |
| EC 8+2 | 80.0% | 2 | 11 | 大集群,效率优先 |
从 3 副本换成 EC 8+2,同样的裸盘能多存 2.4 倍数据。这个诱惑非常大,所以必须清楚代价是什么。
代价一:小 I/O 的写放大
写一个 4KB 的对象到 EC 4+2 池里会发生什么?数据要被切成 4 份(每份 1KB),再算 2 份校验,然后分别发到 6 个不同的 OSD。
- 一次逻辑写变成 6 次网络请求 + 6 次磁盘写
- 每次磁盘写只有 1KB,远小于盘的最优块大小,效率极低
- 客户端必须等最慢的那个 OSD 返回(长尾放大)
这就是为什么 EC 适合大对象顺序写,不适合小文件和随机写。Ceph 的 RBD 池、CephFS 的元数据池默认都用副本而不是 EC,正是这个原因。
代价二:读也要跨多个盘
副本读只需要访问一个 OSD。EC 读在正常情况下也能只读 k 个数据块(Ceph 支持部分读),但一旦有 OSD 故障或慢盘,就必须读齐 k 块做解码——任何一个慢盘都会拖慢整个读请求。
代价三:重建风暴
这是最容易被低估的一项。
- 副本重建:坏一块盘,从持有副本的盘顺序拷贝。参与的盘少,流量集中但可控。
- EC 重建:坏一块盘,要从其余 k 块所在的盘各读一份,再计算还原。恢复 1TB 数据需要读 k TB。
以 EC 8+2 为例,重建 1 块 16TB 的盘,要从其它盘读约 128TB 数据。这些流量和业务 I/O 抢带宽、抢 IOPS,重建期间业务性能下降是必然的。
重建期间集群处于降级状态,容错额度被吃掉一部分。单盘容量越大、EC 的 k 越大,重建就越久,重建期间再坏盘的概率也越高。这就是"单盘不要太大"这条经验的由来——不是盘不好,是重建窗口不好。
故障域:冗余放错位置等于没放
算清空间只是第一步。更重要的是:这几份冗余数据必须落在不同的故障域里。
故障域层级(从小到大)
osd 单块盘
host 单台机器(掉电、内核崩溃、网卡故障)
rack 单个机架(交换机、机架 PDU)
room 机房
如果 3 个副本恰好落在同一台机器的 3 块盘上,那么这台机器一断电,数据就不可读了——冗余度看着是 3,实际容忍度是 0。所以 Ceph 的默认 CRUSH rule 是 failure-domain=host,即三个副本必须在三台不同主机上。
这也解释了 EC 的最少节点数为什么比 k + m 还要多一点:EC 8+2 要求 10 个不同主机各放一块,再加至少 1 台作为故障后的重建目标,实际规划要 11 台起。
- 副本:块存储、数据库、元数据池、小文件多的场景、节点数少于 7 的集群
- EC:对象存储、备份归档、大文件顺序读写为主、节点数充足(12 台以上更从容)
- 一套集群里可以两种混用——Ceph 允许不同的池用不同的冗余策略,这是常规做法而不是奇技淫巧
一套集群有 600TB 裸容量。用 EC 8+2 而不是 3 副本,可用容量大约是多少?(忽略水位和元数据开销)
某集群用 EC 8+3 存放大量 4KB 小文件,用户反馈写入很慢。下面哪些是合理的解释?(多选)
3 个副本被 CRUSH 规则放在了同一台主机的三块盘上。实际的主机级容错能力是?
这节课的落点
- 副本:效率 1/N,恢复是纯拷贝,运维最省心;2 副本不上生产
- EC:效率 k/(k+m),代价是小 I/O 写放大、读长尾放大、重建流量放大 k 倍
- 单盘越大、k 越大,重建窗口越长,降级期间的风险越高
- 冗余必须跨故障域才有意义,部署后要复核实际分布
- 一套集群里按池混用副本和 EC,是标准做法
下一阶段进入 Ceph。你会看到这一节的每一个概念,都在 Ceph 里有对应的具体命令和参数。
延伸资料
- ·Storplan 容量与性能规划 ↗
- ·k8s-in-action
storage/gpfs/day-0-plan-ece.md