分布式系统下的纠删码技术(一) — 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/

 

 

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • jira使用教程_jira 工具

    jira使用教程_jira 工具JIRA使用教程:在Windows上安装JIRA JIRA使用教程:在Linux上安装JIRA JIRA使用教程:使用文件包安装JIRA JIRA使用教程:创建项目 JIRA使用教程:创建问题 JIRA使用教程:搜索问题 JIRA使用教程:编辑项目键 JIRA使用教程:简单问题跟踪 JIRA使用教程:创建软件开发项目 JIRA使用教程:共享搜索结果 JIRA使用教程:查看项目…

    2022年10月21日
    0
  • python用冒泡法排序_数组冒泡排序c语言函数

    python用冒泡法排序_数组冒泡排序c语言函数arr=[7,4,3,67,34,1,8].defbubble_sort:最近在学习Python,下面是我的一些笔记冒泡排序实现思路:使用双重for循环,内层变量为i,外层为j,在内层循环中不断的比较相邻的两个值(i,i+1)的大小,如果i+1的值大于i的值,交换两者位置,每循环一次,外层的j增加1,等到j等于n-1的时候,结束循环第一次看不懂很正常,不要灰心,下面是使用代码的实现arr=…

    2022年10月16日
    0
  • centos7安装python3.6_centos python3安装

    centos7安装python3.6_centos python3安装Centos7下安装Python3的方法由于centos7原本就安装了Python2,而且这个Python2不能被删除,因为有很多系统命令,比如yum都要用到。[root@VM_105_217_centosPython-3.6.2]#pythonPython2.7.5(default,Aug42017,00:39:18)[GCC4.8.520150623(RedHat4.8.5-16)]onlinux2Type”help”,”copyrig…

    2022年9月24日
    0
  • BPTT

    BPTTRNN的BP——BackPropagationThroughTime.参考:零基础入门深度学习(5)-循环神经网络。知乎。1   defbackward(self,sensitivity_array,2activator):3”’4实现BPTT…

    2022年6月23日
    19
  • 提示用微信浏览器打开_浏览器如何设置消息提醒

    提示用微信浏览器打开_浏览器如何设置消息提醒概述大体思路是这样的:先建一个蒙版,蒙版放上提示的信息,然后写一个js,在页面打开的时候判断是不是用微信自带的浏览器打开的,如果是就打开蒙版,提示用浏览器打开基本页面添加蒙版添加js最终效果

    2022年8月16日
    3
  • java 常量池和运行时常量池_运行时常量池和字符串常量池

    java 常量池和运行时常量池_运行时常量池和字符串常量池原文链接:http://tangxman.github.io/2015/07/27/the-difference-of-java-string-pool/                 在java的内存分配中,经常听到很多关于常量池的描述,我开始看的时候也是看的很模糊,网上五花八门的说法简直太多了,最后查阅各种资料,终于算是差不多理清了,很多网上说法都有问题,笔者尝试着来区分…

    2022年7月28日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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