3.1 纠删码原理:从副本到分片


3.1 纠删码原理:从副本到分片

本节摘要:纠删码用"切分、编码、打散"三步,把数据冗余从"多抄几份"变成"多算几份校验",以远低于副本的存储代价换来可控的容错能力。本节把这笔数学账算清楚,讲透 EC 配比的取舍,并说明它对 RAID 的代差为什么是结构性的。

为什么三副本的账越算越亏?

先做一笔每个存储负责人都躲不开的账。假设有 1 PB 数据要保护,容忍两块盘同时坏:走三副本,需要 3 PB 裸容量,利用率 33%;走 EC 8+4(8 个数据分片加 4 个校验分片),需要 1.5 PB 裸容量,利用率 66.7%,同样能容忍任意 4 块盘故障——比三副本的目标还多扛两块。同样一批数据,冗余成本差了一倍,而可靠性反而更高。这就是 MinIO 从第一版起就把纠删码作为唯一数据保护方式的底气。数据规模越大,这笔账的差距越刺眼:到了 10 PB 量级,副本与纠删码的差价足够再建半个机房。

Reed-Solomon:把数据变成方程组

纠删码的数学基座是 Reed-Solomon 编码。把它讲成一个人话版本:把对象切成 k 个数据分片,看作 k 个未知数;用一个精心挑选的编码矩阵对它们做线性组合,算出 m 个校验分片——相当于凭空多出 m 个方程。只要任意 k 个分片(不管数据还是校验)存活,k 个未知数就有唯一解,原始数据就能被解出来。丢的分片不超过 m 个,恢复就是解一道方程组的功夫。

三个工程细节让理论变成了能跑满网卡的现实:

  1. 柯西矩阵取代范德蒙德矩阵:解码时的求逆运算被简化为查表与异或,计算量骤降。
  2. SIMD 指令加速:有限域上的乘法用 AVX2 或 AVX-512 向量指令并行处理,编解码吞吐达到每核每秒数 GB,摆脱了"纠删码很慢"的历史印象。
  3. 分片粒度自动管理:对象按内部块切分,分片大小随对象大小自适应,小对象不会为凑满分片而浪费空间。

图 3-1 纠删码的编码与重构

图 3-1 纠删码的编码与重构

配比的取舍:容错、利用率与读放大

EC 配比 k+m 是一本三头账。用常用配置把它算清楚(纠删集 16 盘为例):

配置 数据分片 校验分片 容错上限 利用率 适合场景
保守 8 8 8 盘 50% 合规归档、极低频访问
均衡 10 6 6 盘 62.5% 通用业务桶
激进 12 4 4 盘 75% 高频读写、成本敏感
高吞吐 14 2 2 盘 87.5% 临时计算数据、可重建数据

三头账的读法:校验分片越多,容错越厚、利用率越低;数据分片越多,一次读要凑齐的分片越多(读放大略增),但吞吐潜力越大。默认值(对半分)是为"不知道你的业务"准备的——知道的话就该显式指定。我们的经验值:普通业务桶 10+6,备份归档桶 8+8,计算中间数据 12+4 或 14+2。配比在对象写入时定格,换配比等于换一批对象,所以配比决策要发生在建桶前。

还有一个容易忽略的维度:读路径只需要 k 个分片即可服务。这意味着单纠删集坏到只剩 k 个分片时,读还能活,但已经没有修复余地——再坏一块数据就永久丢失。监控里要盯的不是"有没有盘坏",而是每个纠删集的可用分片数距离 k 还有多远,这个距离叫健康水位,8.2 的监控章节会给具体指标。

对 RAID 的代差:为什么不能拿 RAID 凑合

"服务器上做 RAID 6 再跑 MinIO 行不行?"行,但你会同时失去两样东西。第一,故障域:RAID 的保护半径是单台服务器的几块盘,机器烧了RAID 毫无办法,而 MinIO 的纠删集跨节点打散,整台服务器宕机都只是掉几个分片。第二,重构速度:RAID 6 重建一块 16T 盘要连续读全组盘、以天计,期间任何一次读写抖动都可能触发 URE(不可读扇区)导致二次故障;MinIO 的重构只读需要的分片、只算丢的对象,粒度细到单对象,天然规避了全组扫描的惊群。更现实的一条:RAID 卡是黑盒,它的缓存策略、直通模式与 MinIO 的直接盘访问互相打架——生产实践里 MinIO 明确要求 HBA 直通而不是 RAID 模式。

案例:一次坏盘的完整消化

背景:四节点 16 盘集群,EC 10+6。监控在周二上午报出 minio-2 的一块盘 media error 频次上升。

操作:值班工程师按流程走:先用管理命令确认该盘所在纠删集的健康水位(仍是满格,坏盘已自动摘除读写);预约换盘窗口,当天下午插入新盘;新盘被集群自动纳为热备位,随后对该纠删集执行一次定向 heal,把迁出的分片重新铺回。

结果:从告警到 heal 完成 4 小时,全程无读写失败,期间该桶的 P99 延迟无可见抖动。换下的盘送修,确认是磁头老化。

解读:这次处理的平静恰恰是设计的成功——告警、摘除、heal 全是既定剧本,没有即兴发挥。要警惕的反而是"没有任何告警"的日子:位衰减这种静默损坏不会喊疼,那是 3.2 的主题。

变式:若坏的不是一块盘而是一整台节点(主板故障),流程不变但水位判断更关键——确认所在集的分片存活数仍在安全线以上,再从容走硬件更换。3.3 会补充此时的行为语义:服务为什么继续、一致性为什么不受影响。

本节要点回顾

  • 冗余是算出来的:EC 用 k 加 m 个分片实现"任意丢 m 个可恢复",空间成本远低于副本。
  • 配比在建桶前定死:默认对半分是为未知业务准备的保守值,配比随对象一生不可更改。
  • 盯健康水位:可用分片数距离 k 的余量才是真正的安全指标,而非"有没有坏盘"。
  • RAID 与纠删码不同层:前者护单机盘、后者护跨节点故障域,生产上直通盘位交给 MinIO。

编码解决了"丢了能算回",但还有一种损坏不报错——比特悄悄变了。下一节讲 MinIO 如何抓贼。

三个延伸疑问

小对象也切分片吗?会不会很浪费?

对象按内部块粒度切分,小对象的分片数量与大小自适应收缩,最小到 KB 级,不存在"1 KB 的对象也要铺满 16 块盘"的浪费。真正需要在意小对象的是每秒操作数与元数据开销,那是 7 章性能画像的议题,与冗余无关。

加密和纠删码叠加,顺序是什么?

数据先加密、后纠删编码。这个顺序带来一个实用性质:分片级重构发生在密文层,任何分片损坏都可以用密文分片算回,不需要密钥参与修复;解密只发生在最终读取时。加密与自愈因此完全解耦,互不拖累。

纠删集内部还能再划分子集吗?

不能。纠删集是分片编队的最小单位,配比与集大小在建池时锁定。想要更细的容灾粒度,工具是桶级别的纠删配比与第 5 章的站点复制,而不是拆集。

把本节的核心换算再压缩成一句话方便记忆:配比 k 加 m,容忍任意 m 个分片丢失,利用率为 k 除以 k 加 m。后续任何容量与冗余的讨论,都从这行字出发。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U