分布式系统下的纠删码技术(一) — Erasure Code (EC)

分布式系统下的纠删码技术(一) — Erasure Code (EC) 近几个月主要参与一个分布式存储系统的纠删码部分(用于数据容错),纠删码在学术界出现比较早,现在ceph,微软的存储系统,Hadoop3.0等都用了EC。文章会分为多篇,主要将ErasureCode,LRC, 以及相关的数学基础,作为学习总结。 一、纠删码简介      分布式系统需要在硬件失效等故障发生后仍然能继续提供服务。就数据而言,HDFS采用每份数据3副本的方式,保…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

 

近几个月主要参与一个分布式存储系统的纠删码部分(用于数据容错),纠删码在学术界出现比较早,现在ceph,微软的存储系统,Hadoop 3.0等都用了EC。文章会分为多篇,主要将Erasure Code,LRC,  以及相关的数学基础,作为学习总结。

 

一、纠删码简介

       分布式系统需要在硬件失效等故障发生后仍然能继续提供服务。就数据而言,HDFS采用每份数据3副本的方式,保证某些数据损失之后仍能继续使用。

数据的容错除了副本还有另一种做法,就是把丢失的数据计算出来。这就是纠删码的思想了。(PS: Spark的数据也可以通过计算恢复,详见spark论文)。

       与副本相比,纠删码的优点在于节省存储空间(见下文解释),缺点在于有计算开销而且修复需要一定时间,而副本损失只要复制出来损失的数据,未损失的数据可以继续提供服务。

 

二、Erasure Codes(EC)原理

       1、朴素的解释

              有下列6个方程组成的方程组

(1)x1 = 1

              (2)x2 = 2

              (3)x3 = 3

              (4)x1 + x2 + x3= 6

              (5)x1 + 2*x2 +4*x3 = 17

              (6)x1 + 3*x2 +9*x3 = 34

              要知道x1,x2,x3三个数的值,只需要上面任意三个方程即可解出来。假设有上面4个方程,有趣的地方出现了,如果丢了一个方程,那么仍然可以用其他三个方程求出x1,x2, x3的值。相当于只多了一个方程就能解决x1,x2,x3任何一个数的值丢失的问题。

              把上面的方程(1)(2)(3)看做是分布式系统的数据,(4)(5)(6)看做是code,那么只要一个code,即使丢了(1)(2)(3)中的任何一个数据都是可以恢复的, 达到这样的效果只需要存储4个方程。 如果采取副本策略,要达到(1)(2)(3)丢失任何一个数据都能恢复的话,只要把(1)(2)(3)三个方程都存储两份,也就是存储了6个方程。于是纠删码比副本策略在存储效率上的优势就体现出来,4/6的比值,节省1/3的空间。实际根据code的多少,存储效率会不一样。

       2、存储系统中的符号约定

              k:数据块的个数

              m:校验块的个数(就是code)

              n:k+m,也就是数据块和校验块的个数总和。

              编码效率:r = k/m

       上面的解释是参照Jerasure库的代码解释的,IntelEC库符号表示不同,但是意义一样,不再赘述。

       3、现有的EC库

              (1)Jerasure库

              http://jerasure.org/

              (2)Intel EC库

       http://www.intel.com/content/www/us/en/storage/erasure-code-isa-l-solution-video.html

 

       实际实验发现,(1)线程不安全,(2)线程安全(本人简单看过一部分代码+1000线程并发测试)

尚未面世的Hadoop 3.0据说要使用EC编码。查资料发现用的应该也是英特尔库。本人近日工作是基于英特尔的EC库封装LRC库, 也就是线程安全的LRC(见后文)。

 

三、模拟EC编码、解码(恢复)的例子

       假设4个data块,2个Code块。

       1、编码

              通用的编码矩阵:

分布式系统下的纠删码技术(一) -- Erasure Code (EC)

 

 4个data块,2个Code块情况下,编码过程如下:

分布式系统下的纠删码技术(一) -- Erasure Code (EC)

   (a)

Code块是:

C0=D0+D1+D2+D3

C1=D0+2*D1+4*D2+8*D3

 

 

图1 EC编码过程

       编码矩阵如上图,Di表示数据块,Ci表示校验块。编码矩阵(encodematrix)组成有两部分,上面是k*k的单位矩阵,下面是m*k的编码矩阵,如图是范德蒙矩阵,Jerasure库用的是范德蒙矩阵,Intel EC提供了范德蒙矩阵和柯西矩阵的实现,奇怪的是Intel EC说范德蒙不一定可逆,柯西一定可逆,所以本人在用Intel EC的时候一直用柯西矩阵。(为什么需要可逆见下文:解码)。

       2、解码

              解码粗浅理解就是未损失的数据块和校验块乘以编码矩阵的逆矩阵可以得到原来的数据。大部分博客感觉也就是能让人有这种粗浅的感觉,所以本文写得更详细一点。

              以4个data块,2个Code块的情况的解码来解释,当code的块数为2时,最多坏掉两块数据块(按照解方程就是四元一次方程,至少4个才能解出来四个元的值)。此处假设一个数据块D1和一个code块C0丢失

              解码过程分为两步:

              (1)根据已有的数据求解出所有的Data块, D0 ~ D3

                      更具体而言,顺序遍历编码矩阵的前n行,顺序选取没有损坏的前k行(意思是该行对应的数据块或者校验块没有损坏)。生成k*k的矩阵 M。本例中M矩阵如下:

 

分布式系统下的纠删码技术(一) -- Erasure Code (EC)  

 

编码encode的时候这几行发生了下面的事情:

 分布式系统下的纠删码技术(一) -- Erasure Code (EC)      (b)

(注:等号右边应该是D0 D2 D3 C1,因为我们假定D1和C0坏掉了)

所以解码的时候,有D0 D2 D3 C1 以及M,很显然可以通过求M的逆矩阵来求出D0D1 D2D3 :

 

                                           分布式系统下的纠删码技术(一) -- Erasure Code (EC)(c)

 

(2)求出损失的数据

              (1)中已经求出来了所有的数据块的内容,而且编码矩阵是知道的,因此可以求出所有的数据,对于本例子,其实是在(c)式子两边同时乘以一个矩阵来求出C0,矩阵很简单,就是相应的编码矩阵的部分:

分布式系统下的纠删码技术(一) -- Erasure Code (EC)

 

于是就求出来了丢失的数据D1和Code C0

结合Intel EC的源码简单再讲下decode生成解码矩阵decodematrix的过程:

(1)顺序遍历编码矩阵的前n行,顺序选取没有损坏的前k行(意思是该行对应的数据块或者校验块没有损坏)。生成k*k的矩阵 M。

(2)求M的逆矩阵 M_inv (后续文章讲怎么求)

(3)求解码矩阵decode matrix,解码矩阵构成:

a) 损失的数据块:损失的数据所在的行对应的M_inv的行复制到decode matric

b)直接上代码…

 

 

Decode matrix的构成的代码:

nsrcerrs就是数据块的损失的个数;

nerrs是总的(数据块加上校验块)损失的个数;

invert_matrix就是上面说的M_inv ;

src_err_list是失效的数据块对应的行的下标(idx);

Gf_mul以及下面的异或符号,简单说下就是EC的矩阵运算都是在有限域进行的。 直接把异或理解成加法, 把gf_mul理解成乘法,然后下面的循环看成矩阵运算很容易明白了…

       for (i = 0; i < nsrcerrs; i++) {

              for (j = 0; j < k; j++) {

                     decode_matrix[k * i + j] = invert_matrix[k * src_err_list[i] + j];

              }

       }

       /* src_err_list from encode_matrix * invert of b for parity decoding */

       for (p = nsrcerrs; p < nerrs; p++) {

              for (i = 0; i < k; i++) {

                     s = 0;

                     for (j = 0; j < k; j++)

                            s ^= gf_mul(invert_matrix[j * k + i],

                                       encode_matrix[k * src_err_list[p] + j]);

 

                     decode_matrix[k * p + i] = s;

              }

       }

 

       3、编码矩阵需要满足的性质

      

              从上面的过程可以看出,编码矩阵必须可逆,否则无法解码,也就无法恢复数据。

              k*k的范德蒙矩阵可逆的简单证明(保研狗,就大一学过线代,如果出错的话求指教):

(1)   范德蒙的性质之一是有求行列式的式子:

分布式系统下的纠删码技术(一) -- Erasure Code (EC)

 

式子来源:

(https://zh.wikipedia.org/wiki/%E8%8C%83%E5%BE%B7%E8%92%99%E7%9F%A9%E9%99%A3)

 

(2)   对于我们用的范德蒙矩阵,ai=i (i = 1,2,3…)

 

所以任意两行ai和aj一定不一样,也就是det(V) 不为0

(3)行列式的值不为0等价于矩阵可逆。

证毕。(略羞耻,因为(1)直接用的人家的结论。也可以从满秩的角度很容易证明)

 

       所以当数据损失之后,选取k*k的矩阵,一定可逆,也就可以继续解码。

 

 

四、编码类型

       1、编码方式

              (1)横式编码(horizontalcodes)

              这种编码方式下,code数据块单独uoweie数据块,而不是和data块放在一起。例如EVENODD编码,RDP编码都是横式编码。

              (2)纵式编码(verticalcodes)

              code存储在数据所在的磁盘,某些块既有数据又有code。如X-code编码。

       2、RS编码

              RS编码是唯一可以满足任意的数据磁盘数目(n)和冗余磁盘数目(m)的MDS(maximum distance separable)的编码方法。解码重构的原理推到中,有一个重要的条件,就是未出错的信息所对应的残余生成矩阵在GF(2w)上满足可逆。

(1) 范德蒙RS编码

范德蒙矩阵满足上述的“可逆”的条件。

 

(2) 柯西RS编码

柯西矩阵满足上述的“可逆”的条件。

       与范德蒙RS编码区别就在于用柯西矩阵代替范德蒙行列式,并且有位运算的方法可以对柯西RS编码中的乘法进行改进,转化为二进制乘法,整个RS编码的运算可以转化为只包含异或的简单运算。(此部分待补充)

 

 

五、分布式系统的工程实现

        1、简单实现方案

              (1)编码

                     在创建数据块以及数据块远远未写满的情况下,使用副本策略做数据容错。当若干数据块(比如k个数据块)都基本写满,则禁止对这些数据块做写(包括修改、删除)等操作。此时进行编码,当编码成功时,删除冗余的数据块副本。此时就从副本策略变成纠删码策略。

              (2)解码

                     a)一个线程定期扫描数据,比如对数据块和校验块做crc校验,如果发现有数据块或者校验块失效,则启动恢复线程。

                     b)恢复线程先根据EC组现有的数据情况,从远程或本地获取必要的数据进行解码,恢复失效数据。

       2、EC的一些优化策略

              本人参与的项目遇到了这种情况。最初在解码前未损失的数据都拉到本地,然后恢复数据。后来发现这样是多余的。于是只顺序拉去必要的数据块。实际如果肯修改相应的EC库的代码,还可以有其他选择策略,比如选择同一机房,同一机器不同磁盘的数据用于恢复(这个时候构造的解码矩阵也有一定变化,需要做相应修改,详见本文的解码矩阵的生成过程)。

 

参考及相关资料:

Hadoop EC的一个实现:

https://sourceforge.net/projects/hadoop-ec/

http://blog.cloudera.com/blog/2016/02/progress-report-bringing-erasure-coding-to-apache-hadoop/

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/222905.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 已解决是什么意思(read和read)

    今天做项目优化的时候,需要把某个页面的分为两个页面,然后就出现了这个错误这个问题不要慌,要么是打错字了,要么就是忘记传这个字段了(我算是粗心了吧,代码2000行,数据太多了),导致了在另一个页面没有找到这个value字段,因为懂问题所在,我的快速解决方法是直接ctrl+f搜.value然后在另一个页面传过来就行了…

  • android layout 将EditText 和Button放在同一行

    android layout 将EditText 和Button放在同一行

  • 手机号归属地数据库;根据手机号查找对应的归属地;[通俗易懂]

    手机号归属地数据库;根据手机号查找对应的归属地;[通俗易懂]我在网上找到了一份手机号+对应归属地的数据库文档。链接:https://pan.baidu.com/s/1MQtDkw3sowNmdSeoVJUbEA密码:tp1o链接:https://pan.baidu.com/s/1pzh_FqXOP_6Ta103K5Cmyw密码:9j5r如有需要,先点赞、关注,再下载。…

  • 奉劝那些想把编程学好的学弟学妹们!呕心沥血,袒露心声,掏心掏肺

    奉劝那些想把编程学好的学弟学妹们!呕心沥血,袒露心声,掏心掏肺CSDN的小伙伴们,大家好,我是沉默王二。作为CSDN的前排博主(18万+关注,有点飘了哈),我接触了太多太多想学编程、想把编程学好的人,有从别的专业转过来的,有零基础自学的,有科班出身的。他们当中的一部分人,学着学着就放弃了,或者还在放弃的路上。所以真的想掏心掏肺给大家谈一谈,在学好编程这条路上,我们该做好哪些心理准备,该怎么去学。01、很遗憾我上大学那会,学校的计算机专业刚成立两年,也就是说,我们是第二批。据说,第一批做小白鼠的学长学姐们,很多在毕业的时候都没从事计算机专业方面的工作。倒

  • 2019工程伦理慕课答案(2019秋)习题及期末答案

    2019工程伦理慕课答案(2019秋)习题及期末答案第一章习题(下)单选题(1/1point)下列哪一项不是工程与技术的区别内容和性质目的活动主体任务、对象和思维方式单选题(1/1point)下列哪一项不是工程活动的特征自主性创造性社会性确定性多选题(1points)下列哪项是工程的完整生命周期中的环节计划设计评估完成判断题(1/1point)计划、设计、建造…

  • 10.22 词法分析程序实验心得

    10.22 词法分析程序实验心得

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号