纠删码是分布式存储系统的关键数据保护方法。这篇博文解释了纠删码如何满足企业对数据保护的要求以及如何在 MinIO 中实现它。
数据保护在任何企业环境中都至关重要,因为硬件故障(特别是驱动器故障)很常见。
传统上,使用不同类型的 RAID 技术或镜像/复制来提供硬件容错能力。镜像和复制依赖于一个或多个完整的数据冗余副本 - 这是一种消耗存储的昂贵方式。 RAID5 和 RAID6 等更复杂的技术提供相同的容错能力,同时减少存储开销。 RAID 是单节点数据保护的良好解决方案,但由于需要耗时的重建操作才能使故障驱动器恢复在线,因此无法扩展。
许多分布式系统使用三向复制来进行数据保护,其中原始数据被完整写入3个不同的驱动器,并且任何一个驱动器都能够修复或读取原始数据。复制不仅在存储利用率方面效率低下,而且在从故障中恢复时操作效率也低下。当驱动器发生故障时,系统会将自身置于只读模式,性能会降低,同时将完整的驱动器完全复制到新驱动器上以替换发生故障的驱动器。
纠删码因其弹性和高效性而被应用于分布式存储的数据保护。它将数据文件分割成数据块和奇偶校验块并对其进行编码,以便即使部分编码数据不可用,也可以恢复主数据。水平可扩展的分布式存储系统依靠纠删码通过跨多个驱动器和节点保存编码数据来提供数据保护。如果驱动器或节点发生故障或数据损坏,可以从其他驱动器和节点上保存的块重建原始数据。
通过跨节点和驱动器条带化数据,纠删码能够容忍与其他技术相同数量的驱动器故障,并且效率更高。有许多不同的纠删码算法,最大距离可分离(MDS)码(例如Reed-Solomon)实现了最大的存储效率。
在对象存储中,要保护的数据单位是对象。一个对象可以存储到 n 个驱动器上。如果 k 表示潜在故障,则 k < n,并且通过 MDS 代码,系统可以保证容忍 n - k 个驱动器故障,这意味着 k 个驱动器足以访问任何对象。
考虑一个大小为 M 字节的对象,每个编码对象的大小为 M/k(忽略元数据的大小)。与上面所示的N路复制相比,纠删码配置为n=5和k=3,分布式存储系统可以容忍2个驱动器的丢失,同时存储效率提高80%。例如,对于 10 PB 的数据复制将需要超过 30 PB 的存储,而对象存储将需要 15-20 PB 才能使用纠删码安全地存储和保护相同的数据。纠删码可以配置为数据与奇偶校验块的不同比率,从而产生一定范围的存储效率。 MinIO 维护了一个有用的纠删码计算器,可帮助确定您环境中的要求。
MinIO 通过每个对象的内联擦除编码(MinIO 官方文档供参考)来保护数据,该编码以汇编代码编写,以提供尽可能高的性能。 MinIO 利用 Intel AVX512 指令充分利用多个节点上的主机 CPU 资源来实现快速擦除编码。标准 CPU、快速 NVMe 驱动器和 100 Gbps 网络支持以接近线速写入纠删码对象。
MinIO 使用 Reed-Solomon 代码将对象条带化为可配置为任何所需冗余级别的数据和奇偶校验块。这意味着在具有 8 个奇偶校验配置的 16 个驱动器设置中,一个对象被条带化为 8 个数据块和 8 个奇偶校验块。即使您丢失了多达 7 ((n/2)–1) 个驱动器,无论是奇偶校验还是数据,您仍然可以从剩余驱动器可靠地重建数据。 MinIO 的实现确保即使多个设备丢失或不可用,也可以读取对象或写入新对象。
MinIO 根据擦除集的大小将对象拆分为数据和奇偶校验块,然后将数据和奇偶校验块随机均匀地分布在一组驱动器上,以便每个驱动器每个对象包含的块不超过一个。虽然一个驱动器可能包含多个对象的数据块和奇偶校验块,但只要系统中有足够数量的驱动器,单个对象的每个驱动器就不会超过一个块。对于版本化对象,MinIO 选择相同的驱动器进行数据和奇偶校验存储,同时在任何一个驱动器上保持零重叠。
下表提供了 MinIO 中纠删码的示例,以及可配置的数据和奇偶校验选项以及随附的存储使用率。
总驱动器数 (n) | 数据驱动器 (d) | 奇偶校验驱动器 (p) | 存储使用率 |
---|---|---|---|
16 | 8 | 8 | 2.00 |
16 | 9 | 7 | 1.79 |
16 | 10 | 6 | 1.60 |
16 | 11 | 5 | 1.45 |
16 | 12 | 4 | 1.34 |
16 | 13 | 3 | 1.23 |
16 | 14 | 2 | 1.14 |
MinIO的后端布局实际上非常简单。每个进来的对象都被分配了一个擦除集。擦除集基本上是一组驱动器,而集群由一个或多个擦除集组成,由磁盘总数决定。
让我们看一个简单的示例来了解 MinIO 中使用的格式和布局。
值得注意的是,该格式与数据与奇偶校验驱动器的比率有关 - 无论我们有四个节点,每个节点有一个驱动器,还是四个节点,每个节点有 100 个驱动器(MinIO 经常部署在密集的 JBOD 配置中)。
我们可以配置四个节点,每个节点有 100 个驱动器,以使用默认大小 16 的擦除集。这是逻辑布局,并且是纠删码计算定义的一部分。每 16 个驱动器是一个擦除集,由 8 个数据驱动器和 8 个奇偶校验驱动器组成。在这种情况下,擦除集基于400个物理驱动器,平均分为数据驱动器和奇偶校验驱动器,并且最多可以容忍175个驱动器的丢失。
MinIO 的 XL 元数据以原子方式与对象一起写入,包含与该对象相关的所有信息。 MinIO 中没有其他元数据。其含义是戏剧性的——一切都与对象独立在一起,保持一切简单和自我描述。 XL元数据指示纠删码算法,例如具有两个奇偶校验的两个数据、块大小和校验和。将校验和与数据本身一起写入允许 MinIO 在支持流数据的同时进行内存优化,与将流数据保存在内存中,然后将其写入磁盘并最终生成 CRC-32 校验和的系统相比,具有明显的优势。
当一个大物体时,即。大于 10 MB 的数据写入 MinIO,S3 API 将其分解为分段上传。部分大小由客户上传时确定。 S3 要求每个部分至少 5 MB(最后一部分除外)且不超过 5 GB。根据 S3 规范,一个对象最多可以有 10,000 个部分。想象一个 320 MB 的对象。如果该对象被分成 64 个部分,MinIO 会将这些部分写入驱动器,如part.1、part.2、...直到part.64。这些部分的大小大致相等,例如,作为分段上传的 320 MB 对象将分为 64 个 5 MB 的部分。
上传的每个部分都在条带上进行了纠删码。 Part.1 是上传的对象的第一个部分,所有部分都在驱动器上水平条带化。每个部分都由其数据块、奇偶校验块和 XL 元数据组成。 MinIO 轮换写入,因此系统不会始终将数据写入相同的驱动器,也不会始终将奇偶校验写入相同的驱动器。每个对象都是独立旋转的,允许统一有效地使用集群中的所有驱动器,同时还增强了数据保护。
为了检索对象,MinIO 执行哈希计算以确定对象的保存位置、读取哈希并访问所需的擦除集和驱动器。读取对象时,会出现 XL 元数据中描述的数据和奇偶校验块。 MinIO 中的默认擦除集是 12 个数据和 4 个奇偶校验,这意味着只要 MinIO 可以读取任意 12 个驱动器,就可以为对象提供服务。
与分布式系统中用于数据保护的其他技术相比,纠删码具有几个关键优势。
纠删码比 RAID 更适合对象存储有几个原因。 MinIO 纠删码不仅可以在多个驱动器和节点发生故障时保护对象免遭数据丢失,而且还可以在对象级别进行保护和修复。与在卷级别修复的 RAID 相比,一次修复一个对象的能力是一个巨大的优势。损坏的对象在 MinIO 中只需数秒即可恢复,而在 RAID 中则需要数小时。如果驱动器出现故障并被更换,MinIO 会识别新驱动器,将其添加到擦除集中,然后验证所有驱动器上的对象。更重要的是,读取和写入不会相互影响,从而实现大规模性能。 MinIO 部署涉及 PB 级存储中的数千亿个对象。
MinIO 中的纠删码实现提高了数据中心的运营效率。与复制不同,驱动器和节点之间不需要冗长的重建或重新同步数据。这听起来可能微不足道,但移动/复制对象可能非常昂贵,而且 16TB 驱动器发生故障并通过数据中心网络复制到另一个驱动器会给存储系统和网络带来巨大的负担。
如果这篇博文激起了您的好奇心,我们提供了更长的纠删码入门手册。立即下载 MinIO并开始使用纠删码保护数据。
也发布在这里。