RS codes的选型

96
炒冷饭
2015.10.25 22:46* 字数 2678

前言

前面的文章里有提到我们为了提高存储集群的可靠性引入了纠删码冗余的方案,其中RS codes因为诸多优点和实现上的便利被广泛采用。同时,我也有说可以用一些办法提高RS的性能表现,另外还可以引入其他编码策略来降低repair traffic.但,由于前文设计的范围太广,不便展开详述,因此,另外写了这篇文章好好探讨一下reed solomon codes

一 什么时候使用RS codes?

这个问题看上去很傻,RS可以帮助我们提高可靠性还可以帮助我们节约成本。这么清晰的理由还用得着再问来问去吗?

我之所以再提一遍,不是因为啰嗦。是因为有些问题我们必须考虑清楚。

首先,对于公有云场景来说,我们不知道用户文件的类型(尤其是size),我们不知道用户的热度,我们也不能控制用户的访问行为。知道这些有什么用呢?

当存储集群仅为自己服务,并且可以确认是较冷数据时,我们自然可以用极其便宜的磁盘和服务器作为RS的物理基础。哪怕是要做数据修复,我们可以暂停业务慢慢来,或者提前有预知可以充分做好准备。但倘若是作为服务提供给众多企业使用那这么做就是相当糟糕的了。

RS codes的symbol分布类似于RAID中stripe的写入方式,好处是读性能提升和磁盘数量线性相关,坏处是任意坏一块盘,读任意文件都要降级去修复数据。虽然数据早晚会回来,但是对于用户来说这段时间就是彻底不可用时间,再加上整个集群随着规模的扩大带宽将非常拥挤,最终你辛辛苦苦做出来的东西在用户眼里就是彻头彻尾的破玩意。

一个好的办法是把RS集群单独出来作为冷数据存储。在业务低峰期将一些长久无人访问的大文件写入RS集群以节约成本。以这种方式,很多可用性和性能问题就可以放到比较低的优先级别去考虑了。当然了,如何做好RS集群和前面的三副本热数据集群的合作又是件颇为麻烦的事情。

二  该如何调整RS的配置?

对于RS来说,最基础的参数有两个,一个是原始data分成多少块symbol,另外是冗余有多少块。显而易见的是,在冗余相同的情况下,data分块的数量越大,总体拥有成本就越低。

但这样的思路会有三个方面表现的问题:

1.需要立即修复的情况增多(因为坏盘在data中的概率上升了)

2.RS encode的速度跟不上那么多磁盘的外部传输速度,带宽也跟不上(写性能并不能线性提高)

3.修复时占用带宽将线性上升(修复需要的块更多了)

尤其是1,2这两个问题直接关系到可用性,除非真的是特别想省钱,能确定应用场景的私有云,否则非常不建议data分成太多块。

另外,考虑到LRC技术(稍后会分析LRC的原理)我们已经不需要傻傻的单纯使用RS了,冗余块数可以进一步降低。说实话,现在上纠删码集群不用LRC那干脆别上了。这不是荣誉的问题,纯粹是因为规模要做大,必须考虑今后的可用性问题。

这里,我先依据经验给到几种方案(依据LRC),稍后介绍完LRC再做计算(三个数字分别为:data symbol,parity symbol,rs parity symbol):

(8,4,2)

(10,4,2)

(12,4,2)

(14,4,2)

其中(12,4,2)是Azure目前的方案

三 RS 性能

3.1 选择实现方式

在确认了自己要使用RS codes和方案之后,我们就要开始尝试实现它了。

如何实现有四条路径可以选择:

1.购买存储服务

有点来头的存储服务商都有这个。省心省力就是多花点钱,存储和方案一锅端。但对于本身就是做存储的服务商来说这个方案就太那个啥了。

2.购买StreamScale公司的big parity产品

目前来看,这家公司的RS至少在一些方面是非常快的(我接触不到他们的产品,是某教授对比的结果)

3.使用开源解决方案

比如backblaze开源了其java解决方案(根据intel的数据,用mapreduce做RS效果非常差,facebook用的是mapreduce :D)

4.自己造轮子

RS的雏形在披头士活跃的年代被提出,已经有一个朝代那么古老了。然而他依然生机勃勃,活跃于各个领域,对于这么一个非常老旧,非常成熟的东西,你要从头写一个更好的实在是有些勉为其难。除非确认开源方案满足不了,再自己造轮子吧。

看来我们得制定标准来对比不同的方案,其实很简单就是编解码的速度都要快。而且也不用真快的没变,反正磁盘写速度和网络带宽也跟不上。够用就行,这标准很低了吧。


根据这个标准,实际上非常多的开源方案都已经达到这个水平了。 :D

3.2 确定策略

我们显然不能将所有symbol放在一个node上,这可用性太低了。但是一旦打散走网络的话,网络开销又太可怕。引入LRC可以缓解这个问题,前文也强调了不做LRC还不如不上纠删码集群。

LRC的实现也有两种办法,第一种是普通青年的办法,比如Azure,对data symbol进行分组,美6块一组做XORs,在坏一块盘的时候(非RS冗余块),网络IO的放大倍数只有6倍。另外一种是文艺青年的做法,比如facebook,他们对RS冗余块也做了XORs,只不过这一块又可以通过之前的分组冗余块计算出来,这样的方式使得当RS冗余块磁盘坏掉的时候,只需要5倍的IO就可以修复了,而不是原先的10倍。除了网络压力小了,这样的办法计算丢失块的速度也快了很多,虽然这个由于磁盘IO限制也体现不出来。

看上去facebook的方案更加高大上,实现起来的难度也不大。但我们要考虑facebook这种方案的历史因素。在引入LRC之前,facebook已经使用RS很久了。他原先的方案是RS(10,4),所以新的方案在不对原有存储基础造成破坏的前提下完成了升级。为了省事,我们也完全可以把RS 冗余块的冗余块直接存下来,比如LRC(10,4,2)的方案就变成了LRC(10,5,2),overhead是0.5,相较于三副本的2来说依然是非常低的。当然对于facebook的方案来说overhead上升了0.1,这意味着每1EB数据你将多存10PB,按照1300元的4TB磁盘来计算,就是325万元。还要不要省事呢?有些人或许会说,这个以后再考虑,当初facebook不是平滑过渡到新方案吗?

但大家可以自行想想看,为什么LRC(10,5,2)无法平滑过渡到LRC(10,4,2)?(指简单运算得到RS两个冗余块的冗余块)

由于LRC带来的诸多好处,我们根本不需要很多的RS冗余块,事实上2块就够了。我们更应该担心的不是很多块磁盘故障来不及修复导致大片的数据丢失,而是unrecoverable read error rate (URE),即扇区读故障导致的一点点数据丢失问题。如何应对这个问题,相关内容比较多,大家可以自行选择策略。另外要说明的是,unrecoverable read error rate (URE) 取值 10^14(1e10),即每10^14 bits发生一次错误。这个数值来源于Bernd Panzer-Steindel. Data integrity. Technical report, CERN/IT, April 2007.但是报告中也没有这个数据的来源。我个人认为可能高度了故障率。另外关于企业级磁盘URE比较低的数据来源还没找到,但确实有这个说法。

如果感兴趣到底修多慢都不怕,也就是运维友好程度的问题。可以使用abl程序,修改其中的修复时间.目前默认的时间是72-120小时修复一块盘。修多快什么时候开始修的运维策略,这才是可靠性的学问。除非你买到了特别糟糕的磁盘。哈哈。不过有好心人给了不同磁盘故障率的实际数据报告。

还需要注意的是abl模拟的结果仅仅是模拟,可靠性模型太复杂了,丢失数据占比太低。它的主要作用是引导大家正确的看待磁盘数据丢失这个问题,去分析真正的原因,而不是在其他方面浪费时间和精力。

四 故事还没完

我的文章总是写的太啰嗦,这次我少说一点。RS的话题还会继续,下一篇我们将封装几个库来跑一遍这个编码。看看不同的库和方法性能到底怎么样?

算术机?