目的
复制很昂贵 - HDFS中的默认3x复制方案在存储空间和其他资源(例如,网络带宽)中具有200%的开销。但是,对于I / O活动相对较低的暖和冷数据集,在正常操作期间很少访问其他块副本,但仍会消耗与第一个副本相同的资源量。
因此,自然的改进是使用擦除编码(EC)代替复制,其提供相同级别的容错并且具有更少的存储空间。在典型的擦除编码(EC)设置中,存储开销不超过50%。EC文件的复制因子没有意义。它始终为1,无法通过-setrep命令进行更改。
背景
在存储系统中,EC最值得注意的用途是廉价磁盘冗余阵列(RAID)。RAID通过条带化实现EC,条带化将逻辑顺序数据(例如文件)划分为更小的单元(例如位,字节或块),并将连续单元存储在不同的磁盘上。在本指南的其余部分中,这个条带分布单元称为条带化单元(或单元)。对于每个原始数据单元条带,计算并存储一定数量的奇偶校验单元 - 其过程称为编码。可以通过基于幸存数据和奇偶校验单元的解码计算来恢复任何条带化单元上的错误。
将EC与HDFS集成可以提高存储效率,同时仍然提供与传统的基于复制的HDFS部署类似的数据持久性。例如,具有6个块的3x复制文件将消耗6 * 3 = 18个磁盘空间块。但是使用EC(6数据,3奇偶校验)部署,它将只消耗9块磁盘空间。
架构
在EC的背景下,条带化具有几个关键优势。首先,它启用在线EC(以EC格式立即写入数据),避免转换阶段并立即节省存储空间。在线EC还通过并行利用多个磁盘轴来增强顺序I / O性能; 这在具有高端网络的集群中尤其可取。其次,它自然地将一个小文件分发到多个DataNode,并且无需将多个文件捆绑到一个编码组中。这极大地简化了文件操作,例如删除,配额报告和联合命名空间之间的迁移。
在典型的HDFS群集中,小文件占总存储消耗的3/4以上。为了更好地支持小文件,在第一阶段的工作中,HDFS支持使用条带化的EC。在未来,HDFS还将支持连续的EC布局。有关详细信息,请参阅设计文档和有关HDFS-7285的讨论。
- NameNode Extensions - 条带化HDFS文件在逻辑上由块组组成,每个块组包含一定数量的内部块。为了减少这些附加块的NameNode内存消耗,引入了新的分层块命名协议。可以从任何内部块的ID推断出块组的ID。这允许在块组级别而不是块级别进行管理。
- 客户端扩展 - 增强了客户端读取和写入路径,以并行处理块组中的多个内部块。在输出/写入路径上,DFSStripedOutputStream管理一组数据流,每个DataNode用于存储当前块组中的内部块。飘带大多是异步工作的。协调器负责整个块组的操作,包括结束当前块组,分配新块组等。在输入/读取路径上,DFSStripedInputStream将请求的逻辑字节数据范围转换为存储在DataNode上的内部块。然后它并行发出读取请求。发生故障时,它会发出额外的解码读取请求。
- DataNode Extensions - DataNode运行额外的ErasureCodingWorker(ECWorker)任务,用于故障擦除编码块的后台恢复。NameNode检测到失败的EC块,然后选择DataNode进行恢复工作。恢复任务作为心跳响应传递。此过程类似于在失败时重新复制复制块的方式。重建执行三个关键任务:
-
- 从源节点读取数据:使用专用线程池从源节点并行读取输入数据。根据EC策略,它会将读取请求计划到所有源目标,并仅读取用于重建的最小数量的输入块。
- 解码数据并生成输出数据:从输入数据中解码新数据和奇偶校验块。所有丢失的数据和奇偶校验块一起解码。
- 将生成的数据块传输到目标节点:解码完成后,将恢复的块传输到目标DataNode。
- 擦除编码策略为了适应异构工作负载,我们允许HDFS集群中的文件和目录具有不同的复制和擦除编码策略。擦除编码策略封装了如何编码/解码文件。每个策略由以下信息定义:
-
- EC模式:这包括EC组中的数据和奇偶校验块的数量(例如,6 + 3),以及编解码器算法(例如,Reed-Solomon,XOR)。
- 条带化单元的大小。这决定了条带化读写的粒度,包括缓冲区大小和编码工作。
策略命名为编解码器 - num数据块 - num奇偶校验块 - 单元大小。目前,支持五种内置策略:RS-3-2-1024k,RS-6-3-1024k,RS-10-4-1024k,RS-LEGACY-6-3-1024k,XOR-2-1- 1024k。
还支持默认的REPLICATION方案。它只能在目录上设置,强制目录采用3x复制方案,而不是继承其祖先的擦除编码策略。此策略可以将3x复制方案目录与擦除编码目录交错。
始终启用REPLICATION。在所有EC策略中,默认情况下启用RS(6,3)。
与HDFS存储策略类似,在目录上设置擦除编码策略。创建文件时,它会继承其最近的祖先目录的EC策略。
目录级EC策略仅影响在目录中创建的新文件。创建文件后,可以查询其擦除编码策略,但不能更改。如果将擦除编码文件重命名为具有不同EC策略的目录,则该文件将保留其现有EC策略。将文件转换为不同的EC策略需要重写其数据; 通过复制文件(例如通过distcp)而不是重命名来完成此操作。
我们允许用户通过XML文件定义自己的EC策略,该文件必须具有以下三个部分:
-
- layoutversion:这表示EC策略XML文件格式的版本。
- schemas:这包括所有用户定义的EC模式。
- policies :这包括所有用户定义的EC策略,每个策略由模式ID和条带化单元的大小(cellsize)组成。
名为user_ec_policies.xml.template的示例EC策略XML文件位于Hadoop conf目录中,用户可以引用该目录。
- 英特尔ISA-L英特尔ISA-L代表英特尔智能存储加速库。ISA-L是为存储应用程序设计的优化低级功能的开源集合。它包括针对Intel AVX和AVX2指令集优化的快速块Reed-Solomon类型擦除代码。HDFS擦除编码可以利用ISA-L来加速编码和解码计算。ISA-L支持大多数主要操作系统,包括Linux和Windows。默认情况下不启用ISA-L。有关如何启用ISA-L,请参阅以下说明。
部署
群集和硬件配置
擦除编码在CPU和网络方面对集群提出了额外的要求。
编码和解码工作在HDFS客户端和DataNode上消耗额外的CPU。
擦除编码要求群集中的数据节点数与配置的EC条带宽度相同。对于EC策略RS(6,3),这意味着至少9个DataNode。
擦除编码文件也分布在机架上,用于机架容错。这意味着在读取和写入条带文件时,大多数操作都是在机架外。因此,网络二分带宽非常重要。
对于机架容错,拥有足够数量的机架也很重要,因此平均而言,每个机架保持的块数不超过EC奇偶校验块的数量。计算它的公式将是(数据块+奇偶校验块)/奇偶校验块,向上舍入。对于EC政策RS(6,3),这意味着最少3个机架(由(6 + 3)/ 3 = 3计算),理想情况下9个或更多来处理计划内和计划外中断。对于机架数量少于奇偶校验单元数量的群集,HDFS无法保持机架容错,但仍会尝试跨多个节点分布条带文件以保留节点级别的容错。因此,建议设置具有相似数量的DataNode的机架。
配置键
默认情况下,禁用所有内置擦除编码策略,但默认情况下启用的dfs.namenode.ec.system.default.policy中定义的策略除外。集群管理员可以根据集群的大小和所需的容错属性,通过hdfs ec [-enablePolicy -policy ]命令启用一组策略。例如,对于具有9个机架的群集,RS-10-4-1024k等策略不会保留机架级容错,而RS-6-3-1024k或RS-3-2-1024k可能更合适。如果管理员只关心节点级容错,只要集群中至少有14个DataNode ,RS-10-4-1024k仍然是合适的。
可以通过'dfs.namenode.ec.system.default.policy'配置配置系统默认EC策略。使用此配置时,如果未在'-setPolicy'命令中将策略名称作为参数传递,则将使用默认EC策略。
默认情况下,'dfs.namenode.ec.system.default.policy'为“RS-6-3-1024k”。
该编解码器实现的用于里德-索罗门和XOR可与以下客户端和数据管理部的配置的键被构造成:io.erasurecode.codec.rs.rawcoders默认RS编解码器,io.erasurecode.codec.rs-legacy.rawcoders用于遗留用于XOR编解码器的RS编解码器,io.erasurecode.codec.xor.rawcoders。用户还可以使用配置键配置自定义编解码器,如:io.erasurecode.codec.self-defined-codec.rawcoders。这些键的值是具有回退机制的编码器名称列表。这些编解码器工厂按配置值指定的顺序加载,直到成功加载编解码器。默认的RS和XOR编解码器配置优先于纯Java的本机实现。没有RS-LEGACY本机编解码器实现,因此默认值仅为纯Java实现。所有这些编解码器都采用纯Java实现。对于默认的RS编解码器,还有一个本机实现,它利用Intel ISA-L库来提高编解码器的性能。对于XOR编解码器,还支持利用Intel ISA-L库来提高编解码器性能的本机实现。有关更多详细信息,请参阅“启用Intel ISA-L”部分。RS Legacy的默认实现是纯Java,
还可以通过以下配置参数调整DataNode上的擦除编码后台恢复工作:
- dfs.datanode.ec.reconstruction.stripedread.timeout.millis - 条带读取的超时。默认值为5000毫秒。
- dfs.datanode.ec.reconstruction.stripedread.buffer.size - 阅读器服务的缓冲区大小。默认值为64KB。
- dfs.datanode.ec.reconstruction.threads - Datanode用于后台重建工作的线程数。默认值为8个线程。
- dfs.datanode.ec.reconstruction.xmits.weight - EC后台恢复任务使用的xmits相对于复制块恢复的相对权重。默认值为0.5。它设置为0以禁用EC恢复任务的计算权重,即EC任务始终具有1个 xmits。擦除编码恢复任务的xmit被计算为读取流的数量和写入流的数量之间的最大值。例如,如果EC恢复任务需要从6个节点读取并写入2个节点,则它具有max( 6,2 )* 0.5 = 3的x。复制文件的恢复任务始终计为1 xmit。NameNode使用dfs.namenode.replication.max-streams减去总xmitsInProgress 在DataNode上,它结合了来自复制文件和EC文件的xmits,以便将恢复任务安排到此DataNode。
启用Intel ISA-L
默认RS编解码器的HDFS本机实现利用Intel ISA-L库来改进编码和解码计算。要启用和使用Intel ISA-L,有三个步骤。
- 构建ISA-L库。有关详细信息,请参阅官方网站“ https://github.com/01org/isa-l/ ”。
- 使用ISA-L支持构建Hadoop。请参阅源代码中(BUILDING.txt)的“构建Hadoop指令”中的“Intel ISA-L构建选项”部分。
- 使用-Dbundle.isal将isal.lib目录的内容复制到最终的tar文件中。使用tar文件部署Hadoop。确保在HDFS客户端和DataNode上可以使用ISA-L。
要验证Hadoop是否正确检测到ISA-L,请运行hadoop checknative命令。
管理命令
HDFS提供ec子命令来执行与擦除编码相关的管理命令。
hdfs ec [generic options] [-setPolicy -path
以下是每个命令的详细信息。
- [-setPolicy -path
在指定路径的目录上设置擦除编码策略。
path:HDFS中的目录。这是一个必需参数。设置策略仅影响新创建的文件,不会影响现有文件。
policyName:用于此目录下的文件的擦除编码策略。如果设置了'dfs.namenode.ec.system.default.policy'配置,则可以省略此参数。路径的EC策略将使用配置中的默认值进行设置。
-replicate在目录上应用默认的REPLICATION方案,强制目录采用3x复制方案。
-replicate和-policy 是可选参数。它们不能同时指定。
- [-getPolicy -path
获取指定路径上文件或目录的擦除编码策略的详细信息。
- [-unsetPolicy -path
取消先前对目录上的setPolicy调用设置的擦除编码策略。如果目录从祖先目录继承了擦除编码策略,则unsetPolicy是no-op。在没有显式策略集的目录上取消设置策略不会返回错误。
- [-listPolicies]
列出在HDFS中注册的所有(启用,禁用和删除)擦除编码策略。只有启用的策略适合与setPolicy命令一起使用。
- [-addPolicies -policyFile ]
添加用户定义的擦除编码策略列表。请参阅etc / hadoop / user_ec_policies.xml.template以获取示例策略文件。最大单元格大小在属性“dfs.namenode.ec.policies.max.cellsize”中定义,默认值为4MB。目前,HDFS允许用户共添加64个策略,添加的策略ID范围为64到127.如果已添加64个策略,则添加策略将失败。
- [-listCodecs]
获取系统中支持的擦除编码编解码器和编码器列表。编码器是编解码器的实现。编解码器可以具有不同的实现,因此具有不同的编码器。编解码器的编码器以后备顺序列出。
- [-removePolicy -policy ]
删除用户定义的擦除编码策略。
- [-enablePolicy -policy ]
启用擦除编码策略。
- [-disablePolicy -policy ]
禁用擦除编码策略。
限制
由于严重的技术挑战,擦除编码文件不支持某些HDFS操作,即hflush,hsync,concat,setReplication,truncate和append。
- 擦除编码文件上的append()和truncate()将抛出IOException。
- 如果文件与不同的擦除编码策略或复制文件混合,concat()将抛出IOException。
- setReplication()在擦除编码文件上是无操作的。
- hflush()和HSYNC()上DFSStripedOutputStream是无操作。因此,在擦除编码文件上调用hflush()或hsync()不能保证数据是持久的。
客户端可以使用StreamCapabilities API来查询OutputStream是否支持hflush()和hsync()。如果客户端希望通过hflush()和hsync()获得数据持久性,那么当前的补救措施是在非擦除编码目录中创建常规3x复制文件等文件,或使用FSDataOutputStreamBuilder#replicate() API创建3x复制文件一个擦除编码的目录。