擦除编码 101
纠删码是分布式存储系统的一种关键数据保护方法。这篇博文解释了纠删码如何满足企业对数据保护的要求,以及它是如何在 MinIO 中实现的。
数据保护和硬件故障
数据保护在任何企业环境中都是必不可少的,因为硬件故障,特别是驱动器故障很常见。
传统上,不同类型的 RAID 技术或镜像/复制用于提供硬件容错。镜像和复制依赖于一个或多个完整的冗余数据副本——这是一种消耗存储的昂贵方式。RAID5 和 RAID6 等更复杂的技术提供相同的容错能力,同时减少存储开销。RAID 是单个节点上数据保护的良好解决方案,但由于将故障驱动器重新联机所需的耗时重建操作而无法扩展。
许多分布式系统使用三向复制来保护数据,其中原始数据被完整地写入 3 个不同的驱动器,并且任何一个驱动器都能够修复或读取原始数据。复制不仅在存储利用率方面效率低下,而且在从故障中恢复时在操作上也效率低下。当驱动器发生故障时,系统会将自身置于只读模式,性能降低,同时将完整的驱动器完全复制到新驱动器上以替换发生故障的驱动器。

纠删码
纠删码被应用于分布式存储的数据保护,因为它具有弹性和效率。它将数据文件拆分为数据和奇偶校验块并对其进行编码,以便即使部分编码数据不可用,也可以恢复主要数据。水平可扩展的分布式存储系统依靠擦除编码通过跨多个驱动器和节点保存编码数据来提供数据保护。如果驱动器或节点发生故障或数据损坏,可以从保存在其他驱动器和节点上的块中重建原始数据。
通过跨节点和驱动器对数据进行条带化,纠删码能够容忍与其他技术相同数量的驱动器故障,而且效率更高。存在许多不同的纠删码算法,其中 Reed-Solomon 等最大距离可分离 (MDS) 代码实现了最大的存储效率。

在对象存储中,被保护的数据单元是一个对象。一个对象可以存储在 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 官方文档)来保护数据,以提供尽可能高的性能。MinIO 利用 Intel AVX512 指令充分利用跨多个节点的主机 CPU 资源进行快速擦除编码。标准 CPU、快速 NVMe 驱动器和 100 Gbps 网络支持以接近线速写入纠删码对象。
MinIO 使用 Reed-Solomon 代码将对象条带化为可以配置为任何所需冗余级别的数据和奇偶校验块。这意味着在具有 8 个奇偶校验配置的 16 个驱动器设置中,一个对象被条带化为 8 个数据和 8 个奇偶校验块。即使丢失多达 7 ((n/2)–1) 个驱动器,无论是奇偶校验还是数据,您仍然可以从其余驱动器可靠地重建数据。MinIO 的实现确保即使多个设备丢失或不可用,也可以读取对象或写入新对象。

MinIO 根据擦除集的大小将对象拆分为数据块和奇偶校验块,然后将数据块和奇偶校验块随机且均匀地分布在一组驱动器中,使得每个驱动器包含的每个对象不超过一个块。虽然一个驱动器可能包含多个对象的数据和奇偶校验块,但只要系统中有足够数量的驱动器,单个对象的每个驱动器不超过一个块。对于版本对象,MinIO 选择相同的驱动器用于数据和奇偶校验存储,同时在任何一个驱动器上保持零重叠。
下表提供了 MinIO 中的纠删码示例,其中包含可配置的数据和奇偶校验选项以及随附的存储使用率。
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 个驱动器,就可以为对象提供服务。
纠删码和 MinIO 实施的好处
与用于分布式系统中的数据保护的其他技术相比,纠删码具有几个关键优势。
擦除编码比 RAID 更适合对象存储有几个原因。MinIO 纠删码不仅可以在多个驱动器和节点发生故障时保护对象免受数据丢失,MinIO 还可以在对象级别进行保护和修复。与在卷级别修复的 RAID 相比,一次修复一个对象的能力是一个巨大的优势。在 MinIO 中可以在几秒钟内恢复损坏的对象,而在 RAID 中则需要几小时。如果驱动器损坏并被更换,MinIO 会识别新驱动器,将其添加到擦除集中,然后验证所有驱动器中的对象。更重要的是,读取和写入不会相互影响,从而实现大规模性能。那里有 MinIO 部署,在 PB 级存储中有数千亿个对象。
MinIO 中的纠删码实现提高了数据中心的运营效率。与复制不同,不需要在驱动器和节点之间进行冗长的重建或重新同步数据。这听起来可能微不足道,但移动/复制对象可能非常昂贵,并且 16TB 驱动器发生故障并通过数据中心网络复制到另一个驱动器会给存储系统和网络带来巨大负担。
如果这篇博文激起了您的好奇心,我们提供了更长的纠删码入门。立即下载 MinIO并开始使用纠删码保护数据。