分布式存储的多副本纠删码简介
本文最后更新于:2024年7月24日 晚上
什么是分布式存储?
介绍多副本和纠删码之前,我们先来说一下分布式存储。分布式存储是不同于传统集中式存储的的一种架构,很多时候也被称为 SDS 即软件定义存储(Software Defined Storage)。
传统集中式存储采用 控制器 + 硬盘柜 的方式,通过冗余的双控制器提供数据管理和读写能力(也有超过 2 个控制器的多控存储,多见于高端存储),通过控制器自带的硬盘槽位或扩展硬盘柜提供存储空间,如下图。
集中式存储的硬盘数据保护多采用 RAID 技术,比如 RAID5、RAID6、RAID10 等。
分布式存储为了实现更灵活的扩展性和更大的存储规模,采用无中心的组网方式,每个存储节点都可以同时提供计算和存储资源 。它们通过 内部交换机 互联起来,基于分布式存储软件提供统一的存储资源池。比如 1 个节点是 200TB 容量,那么 5 个节点就是 1000TB 容量,并可以扩展到数千个节点 EB 级别的容量,所以更适合用在海量数据的场景下。
与集中式存储不同的是,分布式存储的硬盘数据保护多采用 多副本和纠删码 技术。
什么是多副本和纠删码技术?
多副本,顾名思义就是多个数据副本,简单来说就是一个数据拷贝多份完全一样的副本,分别存放在多个不同节点上。比如我们常用的 3 副本(如下图所示)就是将 A 这个数据拷贝了 3 份,分别存放在节点 1、3、4 上,这三个节点是在整个集群中随机选择的,下一个 B 数据有可能就放在节点 1、2、4 上了。
我们来看下多副本的数据保护效果,很明显,当节点 1 和 3 同时故障时,节点 4 上仍然会保存有 A 数据。以此类推,我们可以知道,N 副本技术可以允许 N-1 个节点同时故障数据不丢失。如果是硬盘故障,只要故障硬盘的范围不超过 N-1 个节点,数据也不会丢失,比如节点 1 坏了 3 块盘、节点 3 坏了 4 块盘,数据仍然不会丢失。
理解了什么是多副本之后,我们再来看下什么是纠删码。纠删码的英文全称是 Erasure Code,所以有时我们也会简称为 EC。纠删码顾名思义是一种纠正数据丢失的校验码,大家可以把它类比成一个方程组。我们如果知道 4 个数 a、b、c、d,就可以通过 2 个不同的公式算出 2 个校验数据 x 和 y,把 6 个数据一起保存起来,那么当 a、b、c、d 其中 1 个或 2 个数据丢失的话,就可以通过剩余的 2 个值和计算公式,反推出丢失的 2 个数据。比如:
已知:a+b+c+d=x=10,a+2b+3c+4d=y=20,c=2,d=1
那么:a+b=7,a+2b=10,则 a=4,b=3
当然以上计算只是一个简化的方案,目的是帮助大家理解,真正存储中用的校验方式会比这个复杂得多,但效果是类似的。
如果我们用 M+N 表示纠删码的话,以上就是一个 4+2 的纠删码方案,数据会被切分成 4 个相同大小的分片,并通过校验算法生成 2 个同样大小的校验分片 P 和 Q。比如 32KB 的数据会被切成 4 个 8KB 的分片,再生出 2 个 8KB 的分片,总计 48KB 数据。当 6 个数据分片生成后,它们会被随机存到 6 个不同的节点上(如下图所示)。
和多副本一样,我们来看下 4+2 纠删码的数据保护效果。从上图可以看出,当任意 2 个节点故障时,数据是不会丢失的,因为只会丢失 2 个数据分片,还是可以反算出来的。当然如果同时故障了 3 个节点,4+2 的纠删码是无能为力的,就像 1 个方程有 2 个未知数怎么也解不出来一样。而且 4+2 纠删码也可以允许 2 个节点内任意个数硬盘故障时,数据不丢失。比如节点 1、节点 2 分别故障了 5 块硬盘,也完全不会有影响,因为每一组 4+2 分片都有 4 个分片还在,数据还是可靠的。
多副本和纠删码对存储节点有什么要求?
多副本和纠删码对分布式存储的节点数量和硬盘配置都有一定要求,主要是 2 点:
N 个副本至少需要 N 个节点才能部署,比如 3 副本至少需要 3 个存储节点,而 M+N 纠删码至少需要(M+N)个节点,比如 4+2 纠删码至少需要 6 个节点,当然这只是最低要求,上限并没有限制,另外也不会有倍数比例的要求,比如 3 副本并不要求一定是 6 个、9 个节点,5 个、7 个节点也可以;
每个节点的硬盘数量和单盘容量建议相同 ,因为如果不同的话,就会出现 水桶的短板效应,两个节点,一个节点配置 8TB 硬盘,一个节点配置 4TB 硬盘,8TB 硬盘只能当 4TB 硬盘用,因为每个节点的数据保存容量是随机分布、几乎相同的。
什么是 M+N:1 纠删码?
除了常见的 M+N 纠删码之外,我们还经常见到一种 M+N:1 的纠删码,这是一种特殊的纠删码技术,我们称之为 亚节点纠删码。
这种技术的出现是为了满足小规模集群的部署要求,我们举个例子,有一个用户采购了 3 个分布式存储节点,因为节点数量比较少,他可选的数据冗余策略就只有 3 副本和 2+1 纠删码(2 副本暂不考虑,后文我们来详细说明原因)。选择 3 副本的话,存储的空间利用率就只有 33% 了,如果我们再考虑其他因素,比如硬盘标称值的差异、系统预留空间、热备空间的话,可用空间可能只有 26% 左右,这对于很多看重容量的用户来讲是比较难以接受的。但如果我们选择 2+1 纠删码呢,问题出现了,2+1 纠删码只能允许 1 个分片数据丢失,当集群中 2 个节点分别故障 1 块硬盘的时候,数据就丢失了!
在实际使用场景下,2 块硬盘同时故障的情况虽然比较少见,但概率也并不算低,因为很多用户在 1 块硬盘故障时可能并没有发觉。这段时间存储就是在极其危险的状态下运行,任何硬盘出问题都会导致集群数据丢失,很显然,2+1 纠删码的方案并不好。
基于以上原因,4+2:1 的纠删码出现了。为什么叫亚节点纠删码呢,因为默认的纠删码是按照节点来分配数据的,但 4+2:1 只会 按照硬盘 来分配数据,它把 3 个节点当 6 个节点用,每个节点选择 2 块硬盘,整个集群选择 6 块不同的硬盘来存放 4+2 总计 6 个分片数据(如下图所示)。
我们看到,4+2:1 相比 2+1 纠删码,虽然能容忍节点故障数量仍然是 1 个,但它可以允许 2 个节点分别故障 1 块硬盘(总计故障 2 块硬盘)而数据不丢失。而实际情况下,硬盘故障的概率是远远低于整个节点故障的,所以 4+2:1 还是非常可靠的,而且它的空间利用率远高于 3 副本。当然如果你担心的是 2 个节点同时故障,那你只能选择 3 副本了。
类似于 4+2:1,也存在 8+2:1、16+2:1 等亚节点纠删码,这里我们就不多讨论了。
多副本和纠删码哪个好,应该如何选择?
在比较多副本和纠删码技术时,我们可以从 可用容量、读写性能、重构性能、可靠性 等方面来分析,如下表所示。
在可用容量上,纠删码的优势是较大的,比如 4+2 纠删码的利用率是 66%,但 3 副本只有 33%,两者差了 2 倍,8+2 纠删码更可以做到 80%,这一局纠删码完胜!
在读写性能上,多副本往往会更高,因为纠删码 在写入时涉及数据校验 ,而且可能会产生 写惩罚 , 在读取时更会横跨多个节点 。比如 4+2 纠删码在读取 1 个数据时,需要从 4 个节点分别读取 4 个分片再进行拼接,任何 1 个节点时延过高,都会对性能造成很大影响。而多副本只需要读取 1 个完整的分片即可,不涉及节点的数据拼接。这两者的性能差异在小块 IO 时会较为明显,但如果 IO 块比较大的话, 比如 1MB,那么两者的性能差距就会逐渐缩小,因为这时候写惩罚较少,纠删码也能很好发挥多个节点并发的优势,这一局多副本略胜一筹!
在重构性能上,多副本也会有明显优势,因为 不涉及数据校验,只是单纯的数据拷贝,所以速度比较快。而纠删码的重构涉及反向校验的计算过程,所需要的读写数据量和 CPU 计算消耗都会更大,这一局多副本同样略胜一筹!
ℹ️说明:
重构指的是存储硬盘故障后的数据恢复过程,把故障硬盘的数据恢复到正常的硬盘上,保证数据的完整性。
在可靠性上,多副本和纠删码的故障冗余程度往往差别不大,比如 3 副本和 4+2 纠删码都可以允许任意 2 个节点故障而数据不丢失。但我们也需要注意两点:
- 多副本的重构性能往往比纠删码更快,所以硬盘故障恢复也更快,会带来一些 可靠性上的优势。
- 纠删码可以采用 +3、+4 的策略来容忍更多节点故障,而且空间利用率并不会太低,但如果多副本采用 4 副本、5 副本的话代价就太大了,所以这一点上纠删码有优势。
这一局两者难分伯仲!
综合来看,如果用户更关注性能,尤其是小 IO 的场景,多副本往往是更好的选择,如果用户更关注可用容量,而且是大文件场景的话,纠删码会更合适。
应该具体选择什么规格的纠删码和多副本?
常见的多副本和纠删码策略如下表,我们逐个分析:
2 副本:
不推荐!不推荐!不推荐!重要的事情说 3 遍,因为真的很危险!可能很多用户看重了 2 副本还不错的空间利用率(50%),同时性能也非常好,但选择存储的底线很多时候往往是数据的可靠性,千万不能因小失大。2 副本只能允许任意 1 块硬盘故障,一旦 1 块硬盘故障后,整个集群就处于岌岌可危的状态,任何问题都可能导致所有数据全部丢失。而想想硬盘 每年 1%-2% 的平均故障率,整个集群可能有上百块硬盘,你还想每年都担惊受怕好几次吗?所以除了开发测试场景,完全不担心数据丢失这种情况外,忘了 2 副本吧,它真的很危险!
3 副本:
如果你要选择多副本,那么 2 副本太危险,4 副本太浪费空间,所以 3 副本是最好的选择 。它除了空间利用率低一点之外就没有其他缺点了,在容量要求不高的时候其实成本还是可以接受的。 在块存储、小文件的场景建议采用这种方案。
2+1 纠删码:
同样 不推荐,理由和 2 副本一样,太危险了,而且有 4+2:1 纠删码这个处处比它好的方案在,为什么还要多看 2+1 纠删码一眼呢。
4+2:1 纠删码:
当集群节点数量不足 6 个,没法用 4+2 的情况下,4+2:1 亚节点纠删码无疑是最好的选择,它既可以允许任意 2 块硬盘故障数据不丢失,空间利用率也和 2+1 完全相同。
4+2 纠删码:
当集群节点数 ≥ 6 个时,4+2 纠删码是不错的选择,因为它可以容忍任意 2 个节点的硬盘故障数据不丢失,空间利用率也很高(66%)。
8+2 纠删码:
当集群节点数 ≥ 10 个,而且看重空间利用率大于性能时,8+2 纠删码也是一个选择,它的空间利用率高达 80%,但注意性能可能不理想。
综上所述,当你选择了多副本,3 副本几乎是唯一的选项,当你选择了纠删码,可以根据集群的节点数量进行选择,3-5 个节点时选择 4+2:1,≥6 个节点时选择 4+2,如果你更看重空间利用率,而且不要求高性能的情况,也可以考虑 8+2 纠删码。
除此之外,可能会有人问,5+2、8+3、16+2 等纠删码可不可以用呢?实际上,因为计算机二进制的特点,M+N 纠删码的 M 我们往往取 2 的幂次方,比如 2、4、8、16,这样切片的效率更高,所以 5+2 这类纠删码很少会用。8+3、8+4 这类纠删码虽然比 +2 更可靠,但因为同时故障 3 个、4 个节点的概率太低了,由此带来的性能性下降并不划算,所以也很少使用。16+2 的优势是空间利用率比较高(89%),但性能也较低,所以如果用户的集群规模比较大,对空间利用率要求极高,而且可以容忍一定性能下降的话,16+2 或 16+2:1 在少数场景下也是会被使用的。
以上就是关于分布式存储中多副本和纠删码技术的一些总结,希望对大家有所帮助。