zoukankan      html  css  js  c++  java
  • Erasure Coding(纠删码)深入分析

    http://blog.sina.com.cn/s/blog_57f61b490102viq9.html

    1.前言

    Swift升级到2.0大版本后宣称开始支持纠删码,这其实是一个很有意义的特性,主要是能够在一定程度上解决3副本空间浪费太多的问题。因为3副本这一点是swift推广的最大障碍之一,成本的增加吓退了不少潜在客户。这次的改进有望消除客户顾虑,拓展更多用户

    http://www.openstack.org/blog/2014/07/openstack-swift-2-0-released-and-storage-policies-have-arrived/

    而回到存储领域来看,数据冗余机制其实这几十年来没有太多进展,RAID,副本一直是当仁不让的最终选择。而近几年,尤其是规模较大的应用场景下,纠删码越来越多的出现在选择的视野范围,成为RAID,副本之外的第三种选择,因此也获得了越来越多的关注。

    纠删码(Erasure Code)本身是一种编码容错技术,最早是在通信行业解决部分数据在传输中损耗的问题,它的基本原理是把传输的信号分段,加入一定的校验再让各段间发生一定的联系,即使在传输过程中丢失掉部分信号,接收端仍然能通过算法把完整的信息计算出来。

    如果严格的区分,实际上按照误码控制的不同功能,可分为检错、纠错和纠删三种类型。检错码仅具备识别错码功能 而无纠正错码功能;纠错码不仅具备识别错码功能,同时具备纠正错码功能;纠删码则不仅具备识别错码和纠正错码的功能,而且当错码超过纠正范围时,还可把无法纠错的信息删除。

    前面曾提到过适用场景通常是大规模部署,这是有其缘由的。从传统情况来看,RAID通常用在企业级环境里较多,在几台和十几台存储设备规模的IT系统中,一向是使用稳定可靠历经数十年磨砺的RAID技术。而在数据中心级的大规模部署中,RAID不再受欢迎,大部分的分布式系统都偏好副本模式,看重的是其高可靠性和读性能优化的特点(关于副本的讨论我之前写过一篇:为啥大家都喜欢3副本,是拍脑袋的吗?http://blog.sina.com.cn/s/blog_57f61b490101a8ca.html)。然而副本带来的成本压力实在是有些吃不消,这时候Erasure Code适时出现,以更低成本和更高技术含量提供近似可靠性这几点,就吸引到了众多分布式存储/云存储的厂商和用户。

    2. 纠删码理论分析

    纠删码常见的有三类,Reed-Solomen类,级联低密度纠删码和数字喷泉码,后面两种的实现原理细节和优劣这里就不深入了,这里只简单介绍下目前在存储行业应用的Reed-Solomen类纠删码。

    从纠删码基本的形态来看,它是N个数据+M个校验的结构,其中数据和校验的N和M值都能够按照一定的规则设定。在1~M个数据块(数据或校验都行)损坏的情况下,整体数据仍然可以通过计算剩余数据块上面的数据得出,整体数据不会丢失,存储仍然是可用。

             下面是纠删码的结构示意图。

             说明: C:UsersAdministratorAppDataRoamingFoxmail7Temp-3940-20150121093525Catch.jpg

    从图中其实可以看出,纠删码和大家熟悉的RAID技术看起来是有些类似的,一个条带(Stripe)是由多个数据块(strip)构成,分为数据块和校验块。但与RAID5/RAID6不同的是,纠删码功能上来看最大的区分特点是校验和数据的比例按N+M可调整,并且校验块数量不再受限于两个,典型的如12+4,6+3等等。

    校验块和数据之间是如何建立关系的呢?通信理论(鄙人专业)告诉我们纠删码是属于分组线性编码,编码过程用到的数学理论并不高深,数学关系其实是是矩阵乘法。具体来说是用编码矩阵和分块数据做乘法从而得到校验块,如下:

    说明: 屏幕截图 2014-04-15 19.03.36

    在建立完关联后,由于矩阵运算是可逆,系统就具备了容忍最大M个失效的能力。

    (微软曾在一次演示中用两数之和等于第三个数来解释,但仅是为了方便理解,在真正实践的多校验情况下,还是使用编码矩阵的。)

    https://www.usenix.org/conference/atc12/technical-sessions/presentation/huang

    3. 纠删码的演化,RS->LRC

    纠删码通过技术含量较高的算法,提供和副本近似的可靠性,同时减小了额外所需冗余设备的数量,从而提高了存储设备的利用率。但纠删码所带来的额外负担主要是计算量和数倍的网络负载,优缺点都相当明显。尤其是在出现硬盘故障后,重建数据非常耗CPU,而且计算一个数据块需要通过网络读出N倍的数据并传输,所以网络负载也有数倍甚至10数倍的增加。

    整体来看,若采用纠删码技术,你能够得到了希望的容错能力和存储资源利用率,但是需要接受一定的数据重建代价,两者间做一个平衡。

    难道事情就这个样子了吗?有没有优化改善的空间呢?答案是“有”。

    如果仔细分析故障出现的情况,你将很容易发现两个特征:

    特征一:所有的故障都将导致同样的重建代价,无论是一个盘,还是M个盘

    特征二:单个磁盘故障的几率远远大于多个磁盘同时故障的几率,通常在90%以上

    因此,优化的思路自然聚集到更容易出现的单个磁盘故障上来,如何更有效的处理这种概率较大的事件呢,直接出现的对策就是分组,把单个磁盘故障影响范围缩小到各个组内部,出坏盘故障时,该组内部解决,在恢复过程中读组内更少的盘,跑更少的网络流量,从而减小对全局的影响。

    LRCLocally Repairable Codes,我理解为局部校验编码,其核心思想为:将校验块(parity block)分为全局校验块(global parity)、局部校验块(local reconstruction parity),故障恢复时分组计算。

    说明: Microsoft、Google、Facebook的erasure <wbr><wbr>code技术进展及系统分析

    微软Azure的云存储(Windows Azure Storage)实现为例,它采用LRC(12,2,2)编码,将12个数据块为一组编码,并进一步将这12个数据块平均分为2个本地组, 每个本地组包括6个数据块,并分别计算出一个local parity,之后把所有12个数据块计算出2个global parities。

    当发生任何一个数据块错误时,只需用本地组内的数据和校验块用于计算,即可恢复出原始数据。而恢复代价(通过网络传输的数据块数量)就由传统RS(12,4)编码的12,变为6,恢复过程的网络I/O开销减半,同时空间冗余率保持不变,仍为(12+2+2)/12 = 1.33

    微软在介绍中有过一张图来对RS和LRC进行对比,我觉得描述的非常清楚,这里借用一下
    说明: http://s2.sinaimg.cn/mw690/001BS573gy6OLq2vQVH71&690

    图中,蓝色是LRC,红色是RS,可以很清楚的看到,使用LRC的编码方式后,虽然空间利用率(横轴)并没有提高,但是重建代价(纵轴)却有明显的改善。考虑到分布式系统里故障是一个常态,重建代价的降低和局部化就是非常有价值的一个技术改进了。

    另外,有一点要特别注意,LRC并不是100%不丢数据的,4个块坏掉的情况下,只有86%的几率能找回数据,从可靠性排序来说,RS12+4 》 LRC12+2+2 》RS6+3。

    但综合来说,LRC还是很有竞争力的技术,目前,Microsoft、Google、Facebook、Amazon、淘宝(TFS)都已经在自己的产品中采用了Erasure Code,并且大多都从经典RS转向LRC。虽然具体实现,但基本原理都是LRC的组内校验+全局校验。

    4. 纠删码的实际案例

    我们可以具体来看看在业界,各家优化版纠删码的实现是怎么样的。

    Google RS(6,3) in GFS II (Colossus),

    Google在04年发布GFS的经典论文后,09年开始开发第二代GFS(Colossus),它采用了最基本的RS(6,3)编码,将一个待编码数据单元(Data Unit)分为6个数据块, 再添加3个parity block,最多可容包括parity blocks在内的任意3个数据块错误。

    说明: Microsoft、Google、Facebook的erasure <wbr><wbr>code技术进展及系统分析

    数据恢复的网络I/O开销为:恢复任何一个数据块需要6次I/O,通过网络传输6个数据block,存储的空间冗余率 为(6+3)/6 = 1.5

    由于Google的信息能查阅到的有限,我没找到近两年的情况介绍,但相信Google这样一家技术型的公司,应当也有类似的演进后的纠删码技术,不会止步于5年前的RS标准码。

    Facebook:从RS(10,4)LRC10,6,5

    Facebook早期在HDFS RAID中采用的编码方式RS(10,4)

    说明: Microsoft、Google、Facebook的erasure <wbr><wbr>code技术进展及系统分析

    如上图所示。将每个待编码的数据均分为10个数据块, 后面添加4个校验的parity校验块。这种RS编码方式的空间冗余率为(10+4)/10 = 1.4x,发生任何一个数据块错误的恢复代价为10,即发生任意一个块错误需要10次I/O操作,从网络传输的数据量为10个数据块。

    同样为减少数据恢复的网络I/O代价, FaceBook在13年和加州大学共同发表了论文, XORing Elephants: Novel Erasure Code for Big Data,并把这一成果用在“进阶版HDFS”上

    其LRC编码方法如下:

    说明: Microsoft、Google、Facebook的erasure <wbr><wbr>code技术进展及系统分析

    除了在原先的10个数据块之后添加4个校验块外,还将10个数据块均分为2组,每组单独计算出一个局部校验块(Parity),将数据恢复代价由原来的10降低为5.即恢复任何一个数据块错误只需要进行5次网络I/O,从网络传输5个数据块。此种编码方式的空间冗余率 为(10+4+2)/10 = 1.6。

    4. 结论

    相对副本而言,纠删码(erasure code)的编码技术无疑对存储空间利用率带来很大提升,但由于引入额外的编码、解码运算,对分布式系统的计算能力和网络都有一定额外的要求,简单的理解就是硬件性能要升级,网络环境也得要升级,升级的代价在目前阶段还是一笔不小的预算。

    而由于性能损失的原因,用在本身压力已经很大,很“热”的在线存储系统明显不是很合适,所以目前大多数系统还是把erasure code用于冷数据的离线处理阶段。

    LRC编码由于减少了网络I/O传输的数据量,参与数据恢复运算的数据量和重建时间都基本上能够缩短一倍,但却是以可靠性和空间利用率的一定牺牲为代价的。如何更加有效的实现还是要结合实际项目需求,综合考量,有更多的实际工作要做。

  • 相关阅读:
    什么是高可用?
    URL中两种方式传参
    Flask基本环境配置
    爬虫urlib库的一些用法
    HTML第一部分
    python中递归题
    python中重要的内置函数
    关于生成器中的send,应用移动平均值,以及yield from
    python中装饰器进阶
    一些作业
  • 原文地址:https://www.cnblogs.com/tcicy/p/8456153.html
Copyright © 2011-2022 走看看