什么是纠删码

Erasure Code(简称 EC),即纠删码,是一种前向错误纠正技术(Forward Error Correction,FEC),主要应用在网络传输中避免包的丢失,存储系统利用它来提高存储、可靠性。相比多副本复制而言,纠删码能够以更小的数据冗余度获得更高数据可靠性,但编码方式较复杂,需要大量计算。纠删码只能容忍数据丢失,无法容忍数据篡改,纠删码正是得名与此。

EC 的定义:Erasure Code 是一种编码技术,它可以将 n 份原始数据,增加 m 份数据,并能通过 n+m 份中的任意 n 份数据,还原为原始数据。即如果有任意小于等于 m 份的数据失效,仍然能通过剩下的数据还原出来。

目前,纠删码技术在分布式存储系统中的应用主要有三类,阵列纠删码(Array Code: RAID5、RAID6等)、RS(Reed-Solomon)里德-所罗门类纠删码和 LDPC(LowDensity Parity Check Code)低密度奇偶校验纠删码。

RAID 是 EC 的特殊情况。在传统的 RAID 中,仅支持有限的磁盘失效,RAID5 只支持一个盘失效,RAID6 支持两个盘失效,而 EC 支持多个盘失效。

EC 主要运用于存储和数字编码领域。例如磁盘阵列存储(RAID 5、RAID 6),云存储(RS)等。

LDPC 码也可以提供很好的保障可靠性的冗余机制。与 RS 编码相比,LDPC 编码效率要略低,但编码和解码性能要优于 RS 码以及其他的纠删码,主要得益于编解码采用的相对较少并且简单的异或操作。LDPC 码目前主要用于通信、视频和音频编码等领域。

本文主要讲解 RS 类纠删码。

Reed-Solomon Code
RS code是基于有限域的一种编码算法,有限域又称为Galois Field,是以法国著名数学家伽罗华(Galois)命名的,在RS code中使用GF(2^w),其中2 ^w >= n + m。

RS code 的编解码定义如下:


编码:给定 n 个数据块(Data block)D1、D2……Dn,和一个正整数 m,RS 根据 n 个数据块生成 m 个编码块(Code block),C1、C2……Cm。

RS 编码以 word 为编码和解码单位,大的数据块拆分到字长为 w(取值一般为8或者16位)的 word,然后对 word 进行编解码。数据块的编码原理与 word 编码原理相同,后文中一 word 为例说明,变量 Di, Ci 将代表一个 word。

把输入数据视为向量D=(D1,D2,…, Dn), 编码后数据视为向量(D1, D2,…, Dn, C1, C2,…, Cm),RS 编码可视为如下图所示矩阵运算。

纠删码--分布式存储数据备份_数据块


上图最左边是编码矩阵(或称为生成矩阵、分布矩阵,Distribution Matrix),编码矩阵需要满足任意n*n子矩阵可逆。

为方便数据存储,编码矩阵上部是单位阵(n行n列),下部是m行n列矩阵。下部矩阵可以选择范德蒙德矩阵或柯西矩阵。
RS code编码数据恢复原理
RS最多能容忍m个数据块被删除。数据恢复的过程如下:

(1)假设D1、D4、C2丢失,从编码矩阵中删掉丢失的数据块/编码块对应的行。

纠删码--分布式存储数据备份_分布式_02

根据图1所示RS编码运算等式,可以得到如下B’ 以及等式。

纠删码--分布式存储数据备份_数据块_03


(2)由于B’ 是可逆的,记B’的逆矩阵为 (B’^-1),则B’ * (B’^-1) = I 单位矩阵。两边左乘B’ 逆矩阵

纠删码--分布式存储数据备份_Code_04


(3)得到如下原始数据D的计算公式

纠删码--分布式存储数据备份_数据_05


即恢复原始数据D:

纠删码--分布式存储数据备份_数据块_06


4)对D重新编码,可得到丢失的编码码

RS code编码的限制
数据恢复代价高和数据更新代价高,因此常常针对只读数据,或者冷数据。

RS编码依赖于两张2^w-1大小的log表, 通常只能采用16位或者8位字长,不能充分利用64位服务器的计算能力, 具体实现上可能要做一些优化。

RS编码升级
RS编码后的数据,如果丢失了一块,恢复丢失的数据需要最少读取n块数据。在生产环境中,硬盘故障经常发生,恢复数据对网络IO和CPU都会有较大的消耗。

因此有些公司在EC编码的基础上做了一些改进,使用LRC或SEC替换RS编码。

LRC - Locally Repairable Code 本地副本存储
LRC编码与RS编码方式基本相同,同时增加了额外的数据块副本。 LRC编码本质上是RS编码+2副本备份。

LRC编码步骤如下:

对原始数据使用RS编码,例如编码为4:2,编码结果为4个数据块:D1、D2、D3、D4,2个编码块C1、C2;

原始数据做2副本,将4个数据块的前2个数据块和后2个数据块,分别生成2个编码块,即R1=D1D2,R2=D3D4;

如果某一个数据块丢失,例如D2丢失,则只需要R1和D1即可恢复D2;

LRC的编码矩阵中增加了步骤b的2副本编码,样子如下:

纠删码--分布式存储数据备份_Code_07


SEC - Sparse Erasure Code 稀疏纠删码

LRC编码中只对数据块做了2副本,当编码块丢失时,仍然需要读取n块数据来重新计算编码块。

SEC编码中对数据块和编码块都做增加了校验块。

SEC编码本质上是RS编码+奇偶校验块。 SEC编码步骤如下:

对原始数据使用RS编码,例如编码为4:2,编码结果为4个数据块:D1、D2、D3、D4,2个编码块C1、C2;

生成D1D2的校验块X1,D3D4的校验块X2,C1C2的校验块X3;

当数据块或编码块中的某一个丢失时,例如C2丢失,通过C1和校验块X3即可恢复C2;

SEC同样通过增加存储块,减少了恢复数据是的网络和CPU开销。