故事
景德镇有个规矩,龙窑烧出的贡品进京,一路上碎裂在所难免。早年间用老办法:一器一匣,匣里塞满稻草谷糠,碎了就补送。后来烧造量大了,这条路走不起——一匹马拉三只匣,碎一只就得整匹重跑。
成化年间,有个押运吏姓余,在浮梁县衙的废纸堆里翻出一套前元簿册。簿上记着一件事:至正年间,波斯商人运青花大盘去大食,不用整器,而是把每只碗砸成六片,分装六艘商船。到了忽鲁谟斯,任意取四片就能拼回整碗,多出来的两片防路上沉船。簿册末尾有一行小字:"碎器法,省舱位三分之二,唯器愈大愈宜。"
余吏算了笔账。三只贡碗,老法要三只厚匣、三匹骡马。若把每只碗砸成六片,三只碗共十八片,分装六只薄匣,每匣三片,只要两匹骡马。到了京城,六只匣里任意取四只就能拼出一只整碗——也就是说,六只匣哪怕碎了两只、丢了两只,三只贡碗照样能复原。
他试了一窑。找老师傅定烧三只一模一样的青花缠枝碗,故意在釉下做上只有内行看得出的暗记,然后当着监造太监的面砸碎,分片、编号、装箱。太监脸都绿了,余吏只请他看簿册上的至正年款。
六只薄匣走运河,第四只过徐州时翻了船,第五只在通州码头被窃。余吏到京城交差,剩下四只匣开箱,监造太监亲自动手拼片——三只碗,片片咬合,暗记连贯,竟无一处缺损。
这法子后来进了《大明会典》,但适用范围写得极窄:"大件、远途、不急用者方可。"为什么?余吏的徒弟后来试过把成化斗彩杯也砸六片,结果杯壁太薄,碎处崩口,拼回来漏酒。薄胎器、急用器、需原貌供奉的礼器,仍得整匣运送。
更隐蔽的代价在"拼"字上。整器从匣里取出来就能用,碎器得找齐四片、按编号对位、以漆黏合,耗时半日。兵部有一次急调火炮瞄准具,用的碎器法,结果前锋营在阵前等了三个时辰拼瓷片,误了炮击时机。此后军器一律不准碎器运送。
概念解析
擦除编码的本质,是把"复制"这种空间换可靠性的策略,替换成一种更节省的代数方案。
复制的代价。三副本策略——存三份、 tolerate 两份丢失——可靠但奢侈:每存 1TB 用户数据,实际占用 3TB 磁盘。冷数据越积越多,三副本的沉默成本最终会成为存储集群的最大开销。
碎器法的代数。Reed-Solomon 编码把数据切成 n 块,生成 m 块校验,总共 n+m 块分散存储。任意取其中 n 块即可还原原始数据。典型配置如 RS(10,4):10 块数据 + 4 块校验 = 14 块总存储,可 tolerate 任意 4 块丢失。存储开销从三副本的 3× 降到 1.4×,节省过半。
为什么不是银弹。擦除编码的"拼"——解码重建——需要读取 n 块并做大量矩阵运算,CPU 和带宽消耗远高于直接读一份副本。读取热点数据时,这个延迟不可接受。所以擦除编码只用于"冷"——访问频率极低、容忍重建延迟、追求存储密度优先的场景:对象存储的归档层、备份系统、视频监控的过期录像。
现代工程的分层。AWS S3 Standard 用三副本保证毫秒级读取;S3 Glacier 对归档数据转用擦除编码,把 11 个 9 的持久性维持在极低单价。Facebook 的 f4 系统把温照片(数月无人访问)从 Haystack 的三副本迁移到擦除编码,节省大量磁盘。Google Colossus 的默认策略更细:热数据 Reed-Solomon 短码快速修复,冷数据换更长码率进一步压缩。
薄胎器不能碎。余吏的徒弟漏掉的那条经验——编码块的大小、重建的 CPU 开销、网络带宽的突发消耗——决定了擦除编码的适用边界。小块随机读写(如数据库行存储)用擦除编码是自虐:重建一次读 n 块、算矩阵、拼回来,延迟从毫秒变秒级。对象存储的大块顺序文件才是天然土壤。
《大明会典》把碎器法限在"大件、远途、不急用",和现代的存储分层策略是同一个道理:不是每种数据都值得同等保护,也不是每种保护都该付出同等代价。三副本是整匣运送的厚毡稻草,擦除编码是砸碎分舱的薄匣暗记——冷数据走后者,省下的舱位和骡马,才是存储工程师真正要算的账。