一文读懂Hadoop(二)HDFS



  • 一文读懂Hadoop(二)HDFS(上)

    转自:https://cloud.tencent.com/developer/article/1031641

    1. HDFS优缺点

    1.1 优点

    1.1.1 高容错性

    • 可以由数百或数千个服务器机器组成,每个服务器机器存储文件系统数据的一部分;
    • 数据自动保存多个副本;
    • 副本丢失后检测故障快速,自动恢复。

    1.1.2 适合批处理

    • 移动计算而非数据;
    • 数据位置暴露给计算框架;
    • 数据访问的高吞吐量;
    • 运行的应用程序对其数据集进行流式访问。

    1.1.3 适合大数据处理

    • 典型文件大小为千兆字节到太字节;
    • 支持单个实例中的数千万个文件;
    • 10K+节点。

    1.1.4 可构建在廉价的机器上

    • 通过多副本提高可靠性;
    • 提供了容错与恢复机制。

    1.1.5 跨异构硬件和软件平台的可移植性强

    • 轻松地从一个平台移植到另一个平台。

    1.1.6 简单一致性模型

    • 应用程序需要一次写入多次读取文件的访问模型;
    • 除了追加和截断之外,不需要更改已创建,写入和关闭的文件;
    • 简化了数据一致性问题,并实现了高吞吐量数据访问;
    • 高度可配置,具有非常适合于许多安装的默认配置。大多数时候,只需要为非常大的集群调整配置。

    1.2 缺点

    1.2.1 不适合低延迟的数据访问

    • HDFS设计更多的是批处理,而不是用户交互使用。重点在于数据访问的高吞吐量,而不是数据访问的低延迟。

    1.2.2 不适合小文件存取

    • 占用NameNode大量内存;
    • 寻道时间超过读取时间。

    1.2.3 无法并发写入、文件随即修改

    • 一个文件只能有一个写者;
    • 仅支持追加和截断。

    2. 基本组成

    2.1 Namenode

    2.1.1 接受客户端的读写服务

    执行文件系统命名空间操作,如打开,关闭和重命名文件和目录。

    2.1.2 管理文件系统命名空间

    记录对文件系统命名空间或其属性的任何更改。

    2.1.3 metadata组成

    Metadata是存储在Namenode上的元数据信息,它存储到磁盘的文件名为:fsimage。并且有个叫edits的文件记录对metadata的操作日志。总体来说,fsimage与edits文件记录了Metadata中的权限信息和文件系统目录树、文件包含哪些块、确定块到DataNode的映射、Block存放在哪些DataNode上(由DataNode启动时上报)。

    NameNode将这些信息加载到内存并进行拼装,就成为了一个完整的元数据信息。

    2.1.4 文件系统命名空间

    HDFS支持传统的分层文件组织。用户或应用程序可以在这些目录中创建目录和存储文件。文件系统命名空间层次结构与大多数其他现有文件系统类似:可以创建和删除文件,将文件从一个目录移动到另一个目录,或重命名文件。HDFS支持用户配额和访问权限。但不支持硬链接或软链接。

    NameNode维护文件系统命名空间。对文件系统命名空间或其属性的任何更改由NameNode记录。应用程序可以指定应由HDFS维护的文件的副本数。文件的副本数称为该文件的复制因子。此信息由NameNode存储。

    2.1.5 文件系统元数据的持久性

    NameNode的metadata信息在启动后会加载到内存,由于加载到内存的数据很不安全,断电后就没有了,因此必须对内存中存放的信息做持久化处理。

    Namenode上保存着HDFS的命名空间。对于任何对文件系统元数据产生修改的操作,Namenode都会使用一种称为Edits的事务日志记录下来。例如,在HDFS中创建一个文件,Namenode就会在Edits中插入一条记录来表示;同样地,修改文件的副本系数也将往Edits插入一条记录。Namenode在本地操作系统的文件系统中存储这个Edits。整个文件系统的命名空间,包括数据块到文件的映射、文件的属性等,都存储在一个称为FsImage的文件中,这个文件也是放在Namenode所在的本地文件系统上。

    Namenode在内存中保存着整个文件系统的命名空间和文件数据块映射(Blockmap)的映像。这个关键的元数据结构设计得很紧凑,因而一个有4G内存的Namenode足够支撑大量的文件和目录。当Namenode启动时,它从硬盘中读取Edits和FsImage,将所有Edits中的事务作用在内存中的FsImage上,并将这个新版本的FsImage从内存中保存到本地磁盘上,然后删除旧的Edits,因为这个旧的Edits的事务都已经作用在FsImage上了。这个过程称为一个检查点(checkpoint)。

    Datanode将HDFS数据以文件的形式存储在本地的文件系统中,它并不知道有关HDFS文件的信息。它把每个HDFS数据块存储在本地文件系统的一个单独的文件中。Datanode并不在同一个目录创建所有的文件,实际上,它用试探的方法来确定每个目录的最佳文件数目,并且在适当的时候创建子目录。在同一个目录中创建所有的本地文件并不是最优的选择,这是因为本地文件系统可能无法高效地在单个目录中支持大量的文件。当一个Datanode启动时,它会扫描本地文件系统,产生一个这些本地文件对应的所有HDFS数据块的列表,然后作为报告发送到Namenode,这个报告就是块状态报告。

    2.2 SecondaryNameNode

    它不是NameNode的备份,但可以作为NameNode的备份,当因为断电或服务器损坏的情况,可以用SecondNameNode中已合并的fsimage文件作为备份文件恢复到NameNode上,但是很有可能丢失掉在合并过程中新生成的edits信息。因此不是完全的备份。

    由于NameNode仅在启动期间合并fsimage和edits文件,因此在繁忙的群集上,edits日志文件可能会随时间变得非常大。较大编辑文件的另一个副作用是下一次重新启动NameNode需要更长时间。SecondNameNode的主要功能是帮助NameNode合并edits和fsimage文件,从而减少NameNode启动时间。

    2.2.1 SNN执行合并时机

    • 根据配置文件配置的时间间隔fs.checkpoint.period默认1小时;
    • dfs.namenode.checkpoint.txns,默认设置为1百万,也就是Edits中的事务条数达到1百万就会触发一次合并,即使未达到检查点期间。

    2.2.2 SNN合并流程

    img

    • 首先生成一个名叫edits.new的文件用于记录合并过程中产生的日志信息;
    • 当触发到某一时机时(时间间隔达到1小时或Edits中的事务条数达到1百万)时SecondaryNamenode将edits文件、与fsimage文件从NameNode上读取到SecondNamenode上;
    • 将edits文件与fsimage进行合并操作,合并成一个fsimage.ckpt文件;
    • 将生成的合并后的文件fsimage.ckpt文件转换到NameNode上;
    • 将fsimage.ckpt在NameNode上变成fsimage文件替换NameNode上原有的fsimage文件,并将edits.new文件上变成edits文件替换NameNode上原有的edits文件。

    SNN在hadoop2.x及以上版本在非高可用状态时还存在,但是在hadoop2.x及以上版本高可用状态下SNN就不存在了,在hadoop2.x及以上版本在高可用状态下,处于standby状态的NameNode来做合并操作。

    2.3 DataNode

    • 管理附加到它们运行的节点的存储,并允许用户数据存储在文件中;
    • 在内部,文件被分割成一个或多个块(Block),并且这些块被存储在一组DataNode中;
    • 负责提供来自文件系统客户端的读取和写入请求;
    • 执行块创建,删除;
    • 启动DN进程的时候会向NN汇报Block信息;
    • 通过向NN发送心跳保持与其联系(3秒一次),如果NN10分钟没有收到DN的心跳,则认为DN已经丢失,并且复制其上的Block到其他的DN上。

    2.3.1 HDFS存储单元(block)

    2.3.1.1文件被切分成固定大小的数据块

    • 默认数据块大小为64MB(hadoop1.x)、128MB(hadoop2.x)、256MB(hadoop3.x),可配置;
    • 若文件大小不到一个块大小,则单独存成一个block,block块是一个逻辑意义上的概念。文件大小是多少,就占多少空间。

    2.3.1.2 一个文件存储方式

    • 按大小被切分成不同的block,存储到不同的节点上;
    • 默认情况下,每个block都有3个副本;
    • block大小与副本数通过client端上传文件时设置,文件上传成功后副本数可以变更,block size不可变更。

    2.3.1.3 设计思想

    将大文件拆分成256MB的block块,每个block块分别随机存放在不同的节点上,从而避免了数据倾斜的问题,但是在开发过程中,如果算法、程序写的不好,同样也会出现数据倾斜的问题。

    2.3.2 数据复制

    2.3.2.1 数据复制概述

    HDFS被设计成能够在一个大集群中跨机器可靠地存储超大文件。它将每个文件存储成一系列的数据块,除了最后一个,所有的数据块都是同样大小的。为了容错,文件的所有数据块都会有副本。每个文件的数据块大小和副本系数都是可配置的。应用程序可以指定某个文件的副本数目。副本系数可以在文件创建的时候指定,也可以在之后改变。HDFS中的文件都是一次性写入的,并且严格要求在任何时候只能有一个写入者。

    Namenode全权管理数据块的复制,它周期性地从集群中的每个Datanode接收心跳信号和块状态报告(Blockreport)。接收到心跳信号意味着该Datanode节点工作正常。块状态报告包含了一个该Datanode上所有数据块的列表。

    img

    HDFS数据节点

    2.3.2.2 Block的副本放置策略

    副本的存放是HDFS可靠性和性能的关键。优化的副本存放策略是HDFS区分于其他大部分分布式文件系统的重要特性。这种特性需要做大量的调优,并需要经验的积累。HDFS采用一种称为机架感知(rack-aware)的策略来改进数据的可靠性、可用性和网络带宽的利用率。目前实现的副本存放策略只是在这个方向上的第一步。实现这个策略的短期目标是验证它在生产环境下的有效性,观察它的行为,为实现更先进的策略打下测试和研究的基础。

    大型HDFS实例一般运行在跨越多个机架的计算机组成的集群上,不同机架上的两台机器之间的通讯需要经过交换机。在大多数情况下,同一个机架内的两台机器间的带宽会比不同机架的两台机器间的带宽大。

    通过一个机架感知的过程,Namenode可以确定每个Datanode所属的机架id。一个简单但没有优化的策略就是将副本存放在不同的机架上。这样可以有效防止当整个机架失效时数据的丢失,并且允许读数据的时候充分利用多个机架的带宽。这种策略设置可以将副本均匀分布在集群中,有利于当组件失效情况下的负载均衡。但是,因为这种策略的一个写操作需要传输数据块到多个机架,这增加了写的代价。

    在大多数情况下,副本系数是3,HDFS的存放策略是将一个副本存放在本地机架的节点上,一个副本放在同一机架的另一个节点上,最后一个副本放在不同机架的节点上。这种策略减少了机架间的数据传输,这就提高了写操作的效率。机架的错误远远比节点的错误少,所以这个策略不会影响到数据的可靠性和可用性。于此同时,因为数据块只放在两个(不是三个)不同的机架上,所以此策略减少了读取数据时需要的网络传输总带宽。在这种策略下,副本并不是均匀分布在不同的机架上。三分之一的副本在一个节点上,三分之二的副本在一个机架上,其他副本均匀分布在剩下的机架中,这一策略在不损害数据可靠性和读取性能的情况下改进了写的性能。

    2.3.2.3 副本选择

    为了降低整体的带宽消耗和读取延时,HDFS会尽量让读取程序读取离它最近的副本。如果在读取程序的同一个机架上有一个副本,那么就读取该副本。如果一个HDFS集群跨越多个数据中心,那么客户端也将首先读本地数据中心的副本。

    2.3.2.4 安全模式

    • NameNode在启动的时候会进入一个称为安全模式的特殊状态,它首先将映像文件(fsimage)载入内存,并执行编辑日志(edits)中的各项操作;
    • 一旦在内存中成功建立文件系统元数据映射,则创建一个新的fsimage文件(这个操作不需要SecondNameNode来做)与一个空的编辑日志;
    • 此刻namenode运行在安全模式,即namenode的文件系统对于客户端来说是只读的,显示目录、显示文件内容等,写、删除、重命名都会失败;
    • 在此阶段namenode搜集各个datanode的报告,当数据块达到最小副本数以上时,会被认为是“安全”的,在一定比例的数据块被认为是安全的以后(可设置),再过若干时间,安全模式结束;
    • 当检测到副本数不足数据块时,该块会被复制,直到达到最小副本数,系统中数据块的位置并不是由namenode维护的,而是以块列表形式存储在datanode中。

    2.4 数据组织

    2.4.1 数据块

    HDFS被设计成支持大文件,适用HDFS的是那些需要处理大规模的数据集的应用。这些应用都是只写入数据一次,但却读取一次或多次,并且读取速度应能满足流式读取的需要。HDFS支持文件的“一次写入多次读取”语义。一个典型的数据块大小是256MB。因而,HDFS中的文件总是按照256M被切分成不同的块,每个块尽可能地存储于不同的Datanode中。

    2.4.2 分段

    客户端创建文件的请求其实并没有立即发送给Namenode,事实上,在刚开始阶段HDFS客户端会先将文件数据缓存到本地的一个临时文件。应用程序的写操作被透明地重定向到这个临时文件。当这个临时文件累积的数据量超过一个数据块的大小,客户端才会联系Namenode。Namenode将文件名插入文件系统的层次结构中,并且分配一个数据块给它。然后返回Datanode的标识符和目标数据块给客户端。接着客户端将这块数据从本地临时文件上传到指定的Datanode上。当文件关闭时,在临时文件中剩余的没有上传的数据也会传输到指定的Datanode上。然后客户端告诉Namenode文件已经关闭。此时Namenode才将文件创建操作提交到日志里进行存储。如果Namenode在文件关闭前宕机了,则该文件将丢失。

    上述方法是对在HDFS上运行的目标应用进行认真考虑后得到的结果。这些应用需要进行文件的流式写入。如果不采用客户端缓存,由于网络速度和网络堵塞会对吞估量造成比较大的影响。这种方法并不是没有先例的,早期的文件系统,比如AFS,就用客户端缓存来提高性能。为了达到更高的数据上传效率,已经放松了POSIX标准的要求。

    2.4.3 管道复制

    当客户端向HDFS文件写入数据的时候,一开始是写到本地临时文件中。假设该文件的副本系数设置为3,当本地临时文件累积到一个数据块的大小时,客户端会从Namenode获取一个Datanode列表用于存放副本。然后客户端开始向第一个Datanode传输数据,第一个Datanode一小部分一小部分(4 KB)地接收数据,将每一部分写入本地仓库,并同时传输该部分到列表中第二个Datanode节点。第二个Datanode也是这样,一小部分一小部分地接收数据,写入本地仓库,并同时传给第三个Datanode。最后,第三个Datanode接收数据并存储在本地。因此,Datanode能流水线式地从前一个节点接收数据,并在同时转发给下一个节点,数据以流水线的方式从前一个Datanode复制到下一个。

    3. 读写流程

    3.1 HDFS读流程

    img

    • 首先HDFS的客户端通过DistributedFileSystem;
    • 通过DistributedFileSystem来对NameNode进行请求,同时将用户信息及文件名的信息等发送给NameNode,并返回给DistributedFileSystem该文件包含的block所在的DataNode位置;
    • HDFS客户端通过FSDataInputStream按顺序去读取DataNode中的block信息(它会选择负载最低的或离客户端最近的一台DataNode去读block);
    • FSDataInputStream按顺序一个一个的读,直到所有的block都读取完毕;
    • 当读取完毕后会将FSDataInputStream关闭。

    3.2 HDFS写流程

    img

    • 首先HDFS的客户端通过Distributed FileSystem(HDFS中API里的一个对象);
    • 通过Distributed FileSystem发送客户端的请求给NameNode(NameNode主要是接受客户端请求)并且会带着文件要保存的位置、文件名、操作的用户名等信息一起发送给NameNode;
    • NameNode会给客户端返回了一个FSDataOutputStream,同时也会返回文件要写入哪些DataNode上(负载较低的);
    • 通过FSDataOutputStream进行写操作,在写之前就做文件的拆分,将文件拆分成多个Block,第一个写操作写在负载比较低的DataNode上,并将这个block复制到其他的DataNode上;
    • 当所有的block副本复制完成后会反馈给FSDataOutputStream;
    • 当所有的block副本全都复制完成,就可以将FSDataOutputStream流关闭;
    • 通过Distributed FileSystem更新NameNode中的源数据信息。

    4. 架构

    4.1 NameNode和DataNode

    HDFS采用master/worker架构。一个HDFS集群是由一个Namenode和一定数目的Datanodes组成。Namenode是一个中心服务器,负责管理文件系统的命名空间(namespace)以及客户端对文件的访问。集群中的Datanode一般是一个节点一个,负责管理它所在节点上的存储。HDFS暴露了文件系统的命名空间,用户能够以文件的形式在上面存储数据。从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组Datanode上。Namenode执行文件系统的命名空间操作,比如打开、关闭、重命名文件或目录。它也负责确定数据块到具体Datanode节点的映射。Datanode负责处理文件系统客户端的读写请求。在Namenode的统一调度下进行数据块的创建、删除和复制。

    img

    HDFS架构

    Namenode和Datanode被设计成可以在普通的商用机器上运行。这些机器一般运行着GNU/Linux操作系统(OS)。HDFS采用Java语言开发,因此任何支持Java的机器都可以部署Namenode或Datanode。由于采用了可移植性极强的Java语言,使得HDFS可以部署到多种类型的机器上。一个典型的部署场景是一台机器上只运行一个Namenode实例,而集群中的其它机器分别运行一个Datanode实例。这种架构也可以在一台机器上运行多个Datanode,但这样的情况比较少见。

    集群中单一Namenode的结构大大简化了系统的架构。Namenode是所有HDFS元数据的管理者,用户数据永远不会流过Namenode。

    4.1.1 通信协议

    所有的HDFS通讯协议都是建立在TCP/IP协议之上。客户端通过一个可配置的TCP端口连接到Namenode,通过ClientProtocol协议与Namenode交互。而Datanode使用DatanodeProtocol协议与Namenode交互。一个远程过程调用(RPC)模型被抽象出来封装ClientProtocol和Datanodeprotocol协议。在设计上,Namenode不会主动发起RPC,而是响应来自客户端或 Datanode 的RPC请求。

    4.2 基础架构

    img

    Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件上的分布式文件系统。它和现有的分布式文件系统有很多共同点。但同时,它和其他的分布式文件系统的区别也是很明显的。HDFS是一个高度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。HDFS放宽了一部分POSIX约束,来实现流式读取文件系统数据的目的。HDFS在最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的。HDFS是Apache Hadoop Core项目的一部分。

    • 客户端的请求全部落到了NameNode上;
    • 元数据信息存在NameNode;
    • 在Hadoop集群中有且只有一个处于Active状态的NameNode;
    • SecondaryNameNode不是NameNode的备份节点或从节点(确切的说它只能备份NameNode的部分内容,而不是全部);
    • NameNode与DataNode之间有心跳机制,从而NameNode可以知道DataNode的运行情况与负载情况。

    4.2.1 健壮性

    HDFS的主要目标就是即使在出错的情况下也要保证数据存储的可靠性。常见的三种出错情况是:Namenode出错, Datanode出错和网络分区。

    4.2.1.1 磁盘数据错误,心跳检测和重新复制

    每个Datanode节点周期性地向Namenode发送心跳信号。网络原因有可能导致一部分Datanode跟Namenode失去联系。Namenode通过心跳信号的缺失来检测这一情况,并将这些近期不再发送心跳信号的Datanode标记为宕机,不会再将新的IO请求发给它们。任何存储在宕机Datanode上的数据将不再有效。Datanode的宕机可能会引起一些数据块的副本系数低于指定值,Namenode不断地检测这些需要复制的数据块,一旦发现就启动复制操作。在下列情况下,可能需要重新复制:某个Datanode节点失效、某个副本遭到损坏、Datanode上的硬盘错误或者文件的副本系数增大。

    4.2.1.1.1 DataNode热插拔驱动器

    Datanode支持热插拔驱动器。可以添加或替换HDFS数据卷,而不必不关闭DataNode。下面简要介绍典型的热插拔驱动程序:

    • 如果存在新的存储目录,则应格式化它们并适当地装载它们;
    • 将数据卷目录更新到DataNode的配置dfs.datanode.data.dir中;
    • 通过运行dfsadmin -reconfig datanode HOST:PORT start来使我们配置的目录生效,并且可以使用dfsadmin -reconfig datanode HOST:PORT status查询重新配置任务的运行状态;
    • 一旦重新配置任务完成,我们就可以安全地卸载、删除数据卷目录并物理删除磁盘。

    4.2.1.2 负载均衡

    HDFS的架构支持数据均衡策略。如果某个Datanode节点上的空闲空间低于特定的临界点,按照均衡策略系统就会自动地将数据从这个Datanode移动到其他空闲的Datanode。在对特定文件的突然高需求的情况下,此方案可以动态地创建附加的副本并重新平衡群集中的其他数据。

    4.2.1.2.1 平衡器

    HDFS的数据也许并不是非常均匀的分布在各个DataNode中。一个常见的原因是在现有的集群上经常会增添新的DataNode节点。当新增一个数据块(一个文件的数据被保存在一系列的块中)时,NameNode在选择DataNode接收这个数据块之前,会考虑到很多因素。其中的一些考虑的是:

    • 将数据块的一个副本放在正在写这个数据块的节点上;
    • 尽量将数据块的不同副本分布在不同的机架上,这样集群可在完全失去某一机架的情况下还能存活;
    • 一个副本通常被放置在和写文件的节点同一机架的某个节点上,这样可以减少跨越机架的网络I/O;
    • 尽量均匀地将HDFS数据分布在集群的DataNode中。

    4.2.1.2.2 磁盘平衡器

    Diskbalancer是一个命令行工具,可以将数据均匀分布在数据节点的所有磁盘上。此工具不同于平衡器,它负责群集范围的数据平衡。由于几个原因,数据可能在节点上的磁盘之间具有不均匀分布。这可能是由于大量的写入和删除或由于更换磁盘而发生的。该工具针对给定的数据编码进行操作,并将块从一个磁盘移动到另一个磁盘。

    4.2.1.2.2.1 架构

    磁盘平衡器通过创建计划进行操作,然后在数据节点上执行该计划。一个计划是一组描述两个磁盘之间移动数据的语句。一个计划由多个步骤组成。移动步骤具有源磁盘,目标磁盘和要移动的字节数。可以针对操作数据节点执行计划。

    一共包含3个阶段,Discover(发现)到Plan(计划),再从Plan(计划)到Execute(执行):

    img

    4.2.1.2.2.1.1 Discover

    发现阶段做的事情实际上就是通过计算各个节点内的磁盘使用情况,然后得出需要数据平衡的磁盘列表.这里会通过Volume Data Density磁盘使用密度的概念作为一个评判的标准,这个标准值将会以节点总使用率作为比较值.举个例子,如果一个节点,总使用率为75%,就是0.75,其中A盘使用率0.5(50%),那么A盘的volumeDataDensity密度值就等于0.75-0.5=0.25.同理,如果超出的话,则密度值将会为负数.于是我们可以用节点内各个盘的volumeDataDensity的绝对值来判断此节点内磁盘间数据的平衡情况,如果总的绝对值的和越大,说明数据越不平衡,这有点类似于方差的概念.Discover阶段将会用到如下的连接器对象:

    • DBNameNodeConnector
    • JsonConnector
    • NullConnector

    其中第一个对象会调用到Balancer包下NameNodeConnector对象,以此来读取集群节点,磁盘数据情况。

    4.2.1.2.2.1.2 Plan

    拿到上一阶段的汇报结果数据之后,将会进行执行计划的生成.Plan并不是一个最小的执行单元,它的内部由各个Step组成.Step中会指定好源、目标磁盘.这里的磁盘对象是一层经过包装的对象:DiskBalancerVolume,并不是原来的FsVolume.这里顺便提一下DiskBalancer中对磁盘节点等概念的转化:

    • DiskBalancerCluster.通过此对象可以读取到集群中的节点信息,这里的节点信息以DiskBalancerDataNode的方式所呈现;
    • DiskBalancerDataNode.此对象代表的是一个包装好后的DataNode;
    • DiskBalancerVolume和DiskBalancerVolumeSet.DataNode磁盘对象以及磁盘对象集合.DiskBalancerVolumeSet内的磁盘存储目录类型需要是同种StorageType。

    4.2.1.2.2.1.3 Execute

    最后一部分是执行阶段,所有的plan计划生成好了之后,就到了执行阶段.这些计划会被提交到各自的DataNode上,然后在DiskBalancer类中进行执行.DiskBalancer类中有专门的类对象来做磁盘间数据平衡的工作,这个类名称叫做DiskBalancerMover.在磁盘间数据平衡的过程中,高使用率的磁盘会移动数据块到相对低使用率的磁盘,等到满足一定阈值关系的情况下时,DiskBalancer会渐渐地退出.在DiskBalancer的执行阶段,有以下几点需要注意:

    • 带宽的限制.DiskBalancer中同样可以支持带宽的限制,默认是10M,通过配置dfs.disk.balancer.max.disk.throughputInMBperSec进行控制;
    • 失败次数的限制.DiskBalancer中会存在失败次数的控制.在拷贝block数据块的时候,出现IOException异常,会进行失败次数的累加计数,如果超出最大容忍值,DiskBalancer也会退出;
    • 数据平衡阈值控制.DiskBalancer中可以提供一个磁盘间数据的平衡阈值,以此作为是否需要继续平衡数据的标准,配置项为dfs.disk.balancer.block.tolerance.percent。

    4.2.1.3 数据完整性

    从某个Datanode获取的数据块有可能是损坏的,损坏可能是由Datanode的存储设备错误、网络错误或者软件bug造成的。HDFS客户端软件实现了对HDFS文件内容的校验和(checksum)检查。当客户端创建一个新的HDFS文件,会计算这个文件每个数据块的校验和,并将校验和作为一个单独的隐藏文件保存在同一个HDFS名字空间下。当客户端获取文件内容后,它会检验从Datanode获取的数据跟相应的校验和文件中的校验和是否匹配,如果不匹配,客户端可以选择从其他Datanode获取该数据块的副本。

    4.2.1.3.1 回收站机制

    4.2.1.3.1.1 文件的删除和恢复

    如果启用了回收站功能,FS Shell删除的文件不会立即从HDFS中删除。而是将其移动到回收目录(每个用户在/user /<username>/.Trash下都有自己的回收目录)。只要文件保留在回收站中,文件就可以快速恢复。

    最近删除的文件移动到当前回收目录(/user/<username>/.Trash/Current),并在可配置的时间间隔内,HDFS创建对/user/<username>/.Trash/<date>目录下的一个检查点,并在过期后删除旧检查点。

    当文件在回收站期满之后,NameNode将从HDFS命名空间中删除该文件。删除文件会导致与该文件关联的块被释放。需要说明的是,文件被用户删除的时间和对应的释放空间的时间之间有一个明显的时间延迟。

    4.2.1.3.1.2 减少副本

    当文件的副本因子减小时,NameNode选择可以删除的多余副本。下一个心跳将此信息传输到DataNode。DataNode然后删除相应的块并且释放对应的空间。同样,在设置副本因子完成和集群中出现新的空间之间有个时间延迟。

    4.2.1.4 元数据磁盘错误

    FsImage和Edits是HDFS的核心数据结构。如果这些文件损坏了,整个HDFS实例都将失效。因而,Namenode可以配置成支持维护多个FsImage和Edits的副本。任何对FsImage或者Edits的修改,都将同步到它们的副本上。这种多副本的同步操作可能会降低Namenode每秒处理的命名空间事务数量。然而这个代价是可以接受的,因为即使HDFS的应用是数据密集型的,它们的元数据信息的量也不会很大。当Namenode重启的时候,它会选取最近的完整的FsImage和Edits来使用。

    4.2.1.4.1 检查点节点

    NameNode采用两个文件来保存命名空间的信息:fsimage,它是最新的已执行检查点的命名空间的信息:edits,它是执行检查点后命名空间变化的日志文件。当NameNode启动时,fsimage和edits合并,提供一个最新的文件系统的metadata,然后NameNode将新的HDFS状态写入fsimage,并开始一个新的edits日志。

    Checkpoint节点周期性地创建命名空间的检查点。它从NameNode下载fsimage和edits,在本地合并它们,并将其发回给活动的NameNode。Checkpoint节点通常与NameNode不在同一台机器上,因为它们有同样的内存要求。Checkpoint节点由配置文件中的bin/hdfs namenode –checkpoint来启动。

    Checkpoint(或Backup)节点的位置以及附带的web接口由dfs.namenode.backup.address anddfs.namenode.backup.http-address参数指定。

    Checkpoint进程的运行受两个配置参数控制:

    • dfs.namenode.checkpoint.period,两次连续的检查点之间的最大的时间间隔,缺省值是1小时;
    • dfs.namenode.checkpoint.txns,最大的没有执行检查点的事务数目,默认设置为1百万,也就是Edits中的事务条数达到1百万就会触发一次合并,即使未达到检查点期间;

    Checkpoint节点上保存的最新的检查点,其目录结构与NameNode上一样,这样,如果需要,NameNode总是可以读取这上面的已执行检查点的文件映像。多个Checkpoint节点可以在集群的配置文件中指定。

    4.2.1.4.2 备份节点

    Backup节点与Checkpoint节点提供同样的执行检查点功能,只不过它还在内存中保存一份最新的命名空间的的拷贝,该拷贝与NameNode中的保持同步。除了接收NameNode中发送的edits并把它保存到磁盘之外,Backup还将edits用到自己的内存中,因而创建出一份命名空间的备份。

    因为Backup节点在内存中保持有最新的命名空间的状态,因此它不需要从NameNode下载fsimage和edits文件来创建一个检查点,而这是Checkpoint节点或备用NameNode所必需的步骤。Backup节点的检查点进程更高效,因为它只需要将命名空间信息保存到本地的fsimage文件并重置edits就可以了。

    由于Backup节点内存中维护了一份命名空间的拷贝,它的内存要求与NameNode一致。NameNode同一时刻只支持一个Backup节点。如果Backup在用,则不能注册Checkpont节点。

    Backup节点的配置与Checkpoint节点一样,它采用bin/hdfs namenode –backup启动。Backup(或Checkup)节点的位置及其web接口由配置参数dfs.namenode.backup.address和 dfs.namenode.backup.http-address指定。

    使用Backup节点,NameNode就可以选择不进行存储,而将保持命名空间状态的责任交给Backup节点。为此,在NameNode的配置中,采用选项-importCheckpoint来启动NameNode,并且不设置edits的存储位置选项dfs.namenode.edits.dir。

    4.2.1.4.3 导入检查点

    如果其它所有的映像文件和edits都丢失了,可以将最后的检查点导入到NameNode,为此,需要以下步骤:

    • 创建一个空目录,在dfs.namenode.name.dir项中配置为该目录;
    • 设置dfs.namenode.checkpoint.dir为检查点目录;
    • 采用-importCheckpoint选项来启动NameNode。

    NameNode将从dfs.namenode.checkpoint.dir设置的目录中上载检查点,并将其保存在dfs.namenode.name.dir指定的目录中。如果dfs.namenode.name.dir中存在一个映像文件,NameNode就会启动失败,NameNode要验证dfs.namenode.checkpoint.dir中的映像文件是否有问题,但在任何情况下,都不会修改该文件。

    4.2.1.4.4 恢复模式

    通常,你要配置多个metadata存储位置,当一个存储位置崩溃后,你可以从其它位置读取到metadata。但是,如果仅有的一个存储位置崩溃后怎么办呢?在这种情况下,有一个特别的NameNode启动模式,叫恢复模式,允许你恢复大部分数据。你可以像这样启动恢复模式:namenode –recover,在恢复模式时,NameNode以命令行的方式与你交互,显示你可能采取的恢复数据的措施。如果你不想采用交互模式,你可以加上选项-force,这个选项将强制选取第一个选择恢复,通常,这是最合理的选择。由于恢复模式可能使数据丢失,你应该在使用它之前备份edits日志文件和fsimage。

    4.2.1.4.5 离线Edits文件视图

    离线Edits文件视图是解析Edits日志文件的工具。当前处理器主要用于不同格式之间的转换,包括可读且比本地二进制格式更容易编辑的XML。该工具可以解析Edits日志文件格式(大致Hadoop 0.19)和更高版本。该工具仅对文件操作,它不需要运行Hadoop集群。

    支持的输入格式:

    • **binary:**Hadoop在内部使用的本地二进制格式;
    • **xml:**XML格式,由xml处理器生成,如果filename具有.xml(不区分大小写)扩展名,则使用。

    离线Edits文件视图提供了多个输出处理器(除非另有说明,否则处理器的输出可以转换回原始Edits日志文件):

    • **binary:**Hadoop在内部使用的本地二进制格式;
    • **xml:**XML格式;
    • **stats:**打印出统计信息,不能转换回Edits日志文件。

    4.2.1.4.6 离线Image文件视图

    离线Image文件视图是一个工具,用于将hdfs fsimage文件的内容转储为可读的格式,并提供只读WebHDFS API,以允许离线分析和检查Hadoop集群的命名空间。该工具能够相对快速地处理非常大的image文件。该工具处理Hadoop版本2.4及更高版本中包含的布局格式。如果要处理较早的布局格式,可以使用oiv_legacy Command的离线Image文件视图。如果该工具无法处理fsimage文件,它会完全退出。另外,离线Image文件视图不需要运行Hadoop集群。它完全离线运行。

    离线Image文件视图提供了几个输出处理器:

    • Web是默认的输出处理器。它启动一个HTTP服务器,公开只读WebHDFS API。用户可以通过使用HTTP REST API交互地查看命名空间;
    • XML创建fsimage的XML文档,并包含fsimage中的所有信息。此处理器的输出可通过XML工具进行自动处理和分析;
    • FileDistribution是用于分析命名空间Image中文件大小的工具。为了运行工具,应该通过指定maxSize和一个步骤来定义整数[0,maxSize]的范围。整数范围被分成指定步长的段:[0,s [1],...,s [n-1],maxSize],并且处理器计算系统中有多少文件落入每个段(s [i -1],s [i])。请注意,大于maxSize的文件总是落入最后一个段。默认情况下,输出文件格式化为一个制表符分隔的两个列表:Size和NumFiles。其中Size代表段的开始,numFiles是形成Image的文件数,该大小落在该段中。通过指定选项-format,输出文件将以可读的方式格式化;
    • 分隔:生成一个文本文件,其中包含inode和inode下的inode所共有的所有元素,用分隔符分隔。默认分隔符为\t,但可以通过-delimiter参数更改;
    • ReverseXML:与XML处理器功能相反,它从XML文件重建fsimage。此处理器可以轻松地创建fsimages进行测试。

    4.2.1.5 快照

    HDFS快照是文件系统的只读时间点副本。利用快照,可以让HDFS在数据损坏时恢复到过去一个已知正确的时间点。可以对文件系统的子树或整个文件系统进行快照。快照的一些常见用例是数据备份,防止用户错误和灾难恢复。

    HDFS快照的实现是高效的:

    • 快照创建是即时的:成本是O(1)*,*不包括inode查找时间;
    • 仅当相对于快照进行修改时才使用附加内存:内存使用为O(M),其中M是修改的文件/目录的数量;
    • 不复制datanode中的块:快照文件记录块列表和文件大小。没有数据复制;
    • 快照不会对常规HDFS操作产生不利影响:按照时间倒序顺序记录修改,以便可以直接访问当前数据。通过从当前数据中减去修改来计算快照数据。

    4.2.1.5.1 Snapshottable目录

    一旦目录设置为可快照,就可以对任何目录进行快照。snaphottable目录能够容纳65,536个同步快照。可快照目录的数量没有限制。管理员可以将任何目录设置为可快照。如果快照目录中有快照,则在删除所有快照之前,不能删除或重命名目录。

    当前不允许嵌套snaphottable目录。换句话说,如果一个目录的祖先或后代是一个snaphottable目录,则不能将其设置为snaphottable。

    4.2.2 辅助功能

    4.2.2.1 浏览器界面

    典型的HDFS安装配置Web服务器以通过可配置的TCP端口公开HDFS命名空间。这允许用户使用web浏览器导航HDFS命名空间并查看其文件的内容。

    NameNode和DataNode每个都运行内部Web服务器,以显示有关集群当前状态的基本信息。如果使用默认配置,NameNode 首页位于http://namenode-name:9870/(http://namenode-name:9870/(hadoop3.x)(hadoop3.X)。它列出集群中的DataNode和集群的基本统计信息。Web界面也可以用于浏览文件系统(使用NameNode首页上的“浏览文件系统”链接)。

    4.2.2.2 插件

    有一种用插件访问其内部数据的方式,将hadoop-eclipse-plugin-version.jar包拷贝到eclipse中的plugins目录下,并进行相应的配置,即可直接用eclipse访问HDFS的数据,已及对其进行操作,操作方式与在windows环境操作文件相似。

    4.2.2.3 JAVA编程

    HDFS提供了一个FileSystem Java API,支持用写java代码的方式来访问HDFS的数据。

    4.2.3 可扩展性

    现在,Hadoop已经运行在上千个节点的集群上。HDFS集群只有一个NameNode节点。目前,NameNode上可用内存大小是一个主要的扩展限制。在超大型的集群中,增大HDFS存储文件的平均大小能够增大集群的规模,而不需要增加NameNode的内存。默认配置也许并不适合超大规模的集群。

    4.2.4 文件权限和安全性

    这里的文件权限和其他常见平台如Linux的文件权限类似。R:read w:write x:execute权限x对于文件忽略,对于文件夹表示是否允许访问其内容。如果zhangsan在linux系统中使用hadoop命令创建一个文件,那么这个文件在HDFS中的owner就是zhangsan。

    目前,安全性不仅仅限于简单的文件权限。HDFS还支持网络验证协议(比如Kerberos)来对用户身份进行验证和对数据进行加密传输。

    4.2.4.1 HDFS权限指南

    Hadoop分布式文件系统(HDFS)为共享大多数POSIX模型的文件和目录实现了一个权限模型。每个文件和目录都与所有者和组相关联。文件或目录对作为所有者的用户,对于该组成员的其他用户以及对所有其他用户具有单独的权限。对于文件,读取文件需要r权限,并且需要w权限写入或附加到文件。对于目录,需要r权限列出目录的内容,需要w权限才能创建或删除文件或目录,并且需要x权限才能访问目录的子目录。

    与POSIX模型相反,没有针对文件的setuid或setgid位,因为没有可执行文件的概念。对于目录,没有setuid或setgid bits目录作为简化。防止除超级用户、目录所有者或文件所有者之外的任何人删除或移动目录中的文件。总的来说,文件或目录的权限是它的模式。通常,将使用用于表示和显示模式的Unix习惯,包括使用八进制数。创建文件或目录时,其所有者是客户端进程的用户标识,其组是父目录(BSD规则)的组。

    HDFS还为POSIX ACL(访问控制列表)提供了可选的支持,以通过针对特定命名用户或命名组的细粒度规则扩充文件权限。访问HDFS的每个客户端进程都具有由用户名和组列表组成的两部分身份。每当HDFS必须对客户端进程访问的文件或目录foo执行权限检查时:

    • 如果用户名与foo的所有者匹配,则测试所有者权限;
    • 否则,如果foo的组匹配组列表的任何成员,则测试组权限;
    • 否则,将测试foo的其他权限。

    如果权限检查失败,则客户端操作失败。

    4.3 HDFS高可用性(QJM)

    在Hadoop 2.0.0之前,NameNode是HDFS集群中的单点故障(SPOF)。每个集群都有一个NameNode,如果该机器或进程不可用,则作为整体的集群将不可用,直到NameNode被重新启动或在单独的机器上启动。

    这会以两种主要方式影响HDFS集群的总可用性:

    • 在计划外事件(如计算机崩溃)的情况下,群集将不可用,直到操作员重新启动NameNode;
    • 计划的维护事件(如NameNode计算机上的软件或硬件升级)将导致集群停机时间的窗口。

    HDFS高可用性功能通过在具有热备份的主/从配置中提供在同一集群中运行两个(以及3.0.0或更多个)冗余NameNode的选项来解决上述问题。这允许在机器崩溃的情况下快速故障切换到新的NameNode,或者出于计划维护的目的,由管理员主动发起故障切换。

    4.3.1 原理

    hadoop2.x之后,Clouera提出了QJM/Qurom Journal Manager,这是一个基于Paxos算法实现的HDFS HA方案,它给出了一种较好的解决思路和方案, 在典型的HA群集中,两个或多个单独的计算机配置为NameNode。在任何时间点,只有一个NameNode处于活动状态,而其他的处于待机状态。活动NameNode负责集群中的所有客户端操作,而Standby只维护足够的状态以在必要时提供快速故障转移。示意图如下:

    img

    为了使备用节点保持其与活动节点同步的状态,两个节点都与一组称为“日志节点”(JN)的独立守护进程通信。当活动节点执行任何命名空间修改时,它持久地将修改的记录记录到这些JN中的大多数。备用节点能够从JN读取编辑。

    基本原理就是用2N+1台 JN 存储Edits,每次写数据操作有大多数(>=N+1)返回成功时即认为该次写成功。当然这个算法所能容忍的是最多有N台机器挂掉,如果多于N台挂掉,这个算法就失效了。这个原理是基于Paxos算法。

    在HA架构里面SecondaryNameNode这个角色已经不存在了,为了保持standby NN时时的与主Active NN的元数据保持一致,他们之间交互通过一系列守护的轻量级进程JournalNode

    任何修改操作在 Active NN上执行时,JN进程同时也会记录修改log到至少半数以上的JN中,这时 Standby NN 监测到JN 里面的同步log发生变化了会读取 JN 里面的修改log,然后同步到自己的的目录镜像树里面,如下图:

    img

    当发生故障时,Active的 NN 挂掉后,Standby NN 会在它成为Active NN 前,读取所有的JN里面的修改日志,这样就能高可靠的保证与挂掉的NN的目录镜像树一致,然后无缝的接替它的职责,维护来自客户端请求,从而达到一个高可用的目的。

    为了提供快速故障转移,还必需备用节点具有关于集群中块的位置的最新信息。为了实现这一点,DataNode被配置有所有NameNode的位置,并且向所有NameNode发送块位置信息和心跳。

    4.3.2 QJM的主要优势

    • 不需要配置额外的高共享存储,降低了复杂度和维护成本;
    • 消除spof;
    • 系统健壮的程度是可配置的;
    • JN不会因为其中一台的延迟而影响整体的延迟,而且也不会因为JN的数量增多而影响性能(因为NN向JN发送日志是并行的)。

    4.3.3 只有一个NN能命令DN

    • 每个NN改变状态的时候,向DN发送自己的状态和一个序列号;
    • DN在运行过程中维护此序列号,当failover时,新的NN在返回DN心跳时会返回自己的active状态和一个更大的序列号。DN接收到这个返回则认为该NN为新的active;
    • 如果这时原来的active NN恢复,返回给DN的心跳信息包含active状态和原来的序列号,这时DN就会拒绝这个NN的命令。

    4.3.4 只有一个NN响应客户端

    访问standby nn的客户端直接失败。在RPC层封装了一层,通过FailoverProxyProvider以重试的方式连接NN。通过若干次连接一个NN失败后尝试连接新的NN,对客户端的影响是重试的时候增加一定的延迟。客户端可以设置重试次数和时间。

    Hadoop提供了ZKFailoverController角色,部署在每个NameNode的节点上,作为一个deamon进程, 简称zkfc,示例图如下:

    img

    4.3.5 FailoverController组成

    • **HealthMonitor:**监控NameNode是否处于unavailable或unhealthy状态。当前通过RPC调用NN相应的方法完成;
    • **ActiveStandbyElector:**管理和监控自己在ZK中的状态;
    • **ZKFailoverController:**它订阅HealthMonitor 和ActiveStandbyElector 的事件,并管理NameNode的状态。

    4.3.6 ZKFailoverController职责

    • 健康监测:周期性的向它监控的NN发送健康探测命令,从而来确定某个NameNode是否处于健康状态,如果机器宕机,心跳失败,那么zkfc就会标记它处于一个不健康的状态;
    • 会话管理:如果NN是健康的,zkfc就会在zookeeper中保持一个打开的会话,如果NameNode同时还是Active状态的,那么zkfc还会在Zookeeper中占有一个类型为短暂类型的znode,当这个NN挂掉时,这个znode将会被删除,然后备用的NN,将会得到这把锁,升级为主NN,同时标记状态为Active;
    • 当宕机的NN新启动时,它会再次注册zookeper,发现已经有znode锁了,便会自动变为Standby状态,如此往复循环,保证高可靠,目前可以支持两个以上NN;
    • master选举:如上所述,通过在zookeeper中维持一个短暂类型的znode,来实现抢占式的锁机制,从而判断哪个NameNode为Active状态。

    注意,在HA群集中,Standby NameNode还执行命名空间状态的检查点,因此不需要在HA群集中运行Secondary NameNode,CheckpointNode或BackupNode。

    4.4 HDFS高可用性(NFS)

    NFS的方式的HA的配置与启动,和QJM方式基本上是一样,唯一不同的地方就是active namenode和standby namenode共享edits文件的方式。QJM方式是采用journalnode来共享edits文件,而NFS方式则是采用NFS远程共享目录来共享edits文件。

    NFS允许用户像访问本地文件系统一样访问远程文件系统,而将NFS引入HDFS后,用户可像读写本地文件一样读写HDFS上的文件,大大简化了HDFS使用,这是通过引入一个NFS gateway服务实现的,该服务能将NFS协议转换为HDFS访问协议,具体如下图所示。

    img

    4.5 HDFS Federation

    4.5.1 HDFS的两个主要层

    • 命名空间
    • 由目录,文件和块组成;
    • 它支持所有与命名空间相关的文件系统操作,如创建,删除,修改和列出文件和目录。
    • 块存储服务

    包括两部分:

    • 块管理(在Namenode中执行)

    ①通过处理注册和定期心跳提供Datanode集群成员身份;

    ②处理并维护块的位置;

    ③支持块相关操作,如创建,删除,修改和获取块位置;

    ④管理副本放置,低复制块的块复制,以及删除超过复制的块。

    • 存储

    由Datanodes通过在本地文件系统上存储块并允许读/写访问来提供。

    先前的HDFS架构仅允许整个集群使用单个命名空间。在该配置中,单个Namenode管理命名空间。HDFS Federration通过向HDFS添加对多个Namenodes /命名空间的支持来解决此限制。

    4.5.2 原理

    单Active NN的架构使得HDFS在集群扩展性和性能上都有潜在的问题,当集群大到一定程度后,NN进程使用的内存可能会达到上百G,NN成为了性能的瓶颈。

    常用的估算公式为1G对应1百万个块,按缺省块大小计算的话,大概是64T (这个估算比例是有比较大的富裕的,其实,即使是每个文件只有一个块,所有元数据信息也不会有1KB/block)。

    为了水平扩展名称服务,Federration使用多个独立的Namenodes/命名空间。Namenodes之间管理的数据是共享的,但同时也是独立的,不需要彼此协调。Datanodes被所有Namenode用作块的公共存储。每个Datanode注册集群中的所有Namenode。Datanodes发送定期心跳和块报告。它们还处理来自Namenode的命令。

    为了解决这个问题,Hadoop 2.x、Hadoop 3.x提供了HDFS Federation, 示意图如下:

    img

    多个NN共用一个集群里的存储资源,每个NN都可以单独对外提供服务。

    每个NN都会定义一个存储池,有单独的id,每个DN都为所有存储池提供存储。

    DN会按照存储池id向其对应的NN汇报块信息,同时,DN会向所有NN汇报本地存储可用资源情况。

    如果需要在客户端方便的访问若干个NN上的资源,可以使用客户端挂载表,把不同的目录映射到不同的NN,但NN上必须存在相应的目录。

    4.5.3 设计优势

    • 改动最小,向前兼容;现有的NN无需任何配置改动;如果现有的客户端只连某台NN的话,代码和配置也无需改动;
    • 分离命名空间管理和块存储管理;
    • 客户端挂载表:通过路径自动对应NN、使Federation的配置改动对应用透明。

    4.5.4 ViewF

    View文件系统(ViewFs)提供了一种管理多个Hadoop文件系统命名空间(或命名空间卷)的方法。它对于在HDFS Federation中具有多个命名空间的集群特别有用。ViewF类似于一些Unix/Linux系统中的客户端安装表。ViewF可用于创建个性化命名空间视图以及每个集群的常见视图。

    View文件系统具有多个集群的Hadoop系统的上下文中显示,每个集群可以联合到多个命名空间中,以提供每个群集的全局命名空间,以便应用程序可以以类似于联合前的方式运行。

    4.5.4.1 单个Namenode集群

    在HDFS联合之前,集群具有单个命名空间,为该集群提供单个文件系统命名空间。如果有多个集群。则每个集群的文件系统命名空间是完全独立和不相交的。此外,物理存储不是在集群之间共享(即Datanodes不是跨集群共享的)。

    4.5.4.2 Federation和ViewF

    如果有多个集群。每个集群都有一个或多个命名空间。每个namenode都有自己的命名空间。namenode属于一个且仅一个集群。但是与单个namenode集群不同的是:同一集群中的namenode共享该集群的物理存储。集群中的命名空间与前面一样是独立的。

    操作根据存储需求决定群集中每个namenode上存储的内容。例如,他们可以将所有用户数据(/user/<username>)放在一个命名空间中,将所有feed数据(/data)放置在另一个命名空间中,将所有项目(/projects)放在另一个命名空间等等。

    4.5.4.3 使用ViewF的每个集群的全局命名空间

    为了提供透明度,ViewF文件系统(即客户端装载表)用于创建每个集群独立的集群命名空间视图,这与单个Namenode集群中的命名空间类似。客户端安装表(如Unix安装表),并使用旧的命名约定安装新的命名空间卷。下图显示了装载四个命名空间卷/user,/data,/projects和/tmp的装载表:

    img

    ViewF实现了Hadoop文件系统接口,就像HDFS和本地文件系统一样。这是一个普通的文件系统,它只允许链接到其他文件系统。所有shell命令与ViewFS一起使用,与HDFS和本地文件系统一样。



  • 5. 命令指南

    所有的hadoop命令均由bin/hdfs脚本引发。不指定参数运行hdfs脚本会打印所有命令的描述。

    用法:hdfs [SHELL_OPTIONS] COMMAND [GENERIC_OPTIONS] [COMMAND_OPTIONS]

    Hadoop有一个选项解析框架用于解析一般的选项和运行类。

    img

    5.1 用户命令

    hadoop集群用户的常用命令。

    5.1.1 classpath

    打印获取Hadoop jar和所需库所需的类路径。如果无参数调用,则打印由命令脚本设置的类路径,可以在类路径条目中包含通配符。其他选项在通配符扩展后打印类路径或将类路径写入jar文件的清单。后者在不能使用通配符且扩展的类路径超过支持的最大命令行长度的环境中非常有用。

    5.1.2 dfs

    HDFS允许以文件和目录的形式组织用户数据。它提供了一个称为FS shell的命令行界面,允许用户与HDFS中的数据交互。此命令集的语法类似于我们已经熟悉的shell。

    img

    FS shell是针对需要脚本语言以与存储的数据交互的应用程序。具体命令将在手把手教环节来详细讲解。

    5.1.3 envvars

    显示计算的Hadoop环境变量。

    5.1.4 fetchdt

    HDFS支持fetchdt命令来获取授权标识,并将其存储在本地文件系统的一个文件中。一个“非安全”的客户端可以用这个标识来访问受限的服务器(例如NameNode)。获取这个标识,采用RPC或HTTPS(over Kerberos)方式,然后,在获取之前需要提交Kerberos凭证(运行kinit来获得凭证)。HDFS fechedt命令不是一个Hadoop shell命令。它以bin/hadoop fetchdt DTfile方式运行。当你获得授权标识后,通过指定环境变量HADOOP_TOKEN_FILE_LOCATION为授权标识文件名,你就可以运行HDFS命令,而不需要Kerberros凭证了。

    5.1.5 fsck

    HDFS支持fsck命令来检查系统中的各种不一致状况。这个命令被设计来报告各种文件存在的问题,比如文件缺少数据块或者副本数目不够。不同于在本地文件系统上传统的fsck工具,这个命令并不会修正它检测到的错误。一般来说,NameNode会自动修正大多数可恢复的错误。HDFS的fsck不是一个Hadoop shell命令。它通过'bin/hadoop fsck'执行。

    5.1.6 getconf

    从配置目录获取配置信息。

    5.1.7 groups

    返回给定一个或多个用户名的组信息。

    5.1.8 lsSnapshottableDir

    获取快照目录的列表。当它作为超级用户运行时,它返回所有可快照目录。否则,它返回那些由当前用户拥有的目录。

    5.1.9 jmxget

    从服务转储JMX信息。

    5.1.10 oev

    Hadoop离线edits查看器。

    5.1.11 oiv

    Hadoop离线image查看器用于Hadoop 2.4或更高版本中的映像文件。

    5.1.12 oiv_legacy

    Hadoop的旧版本的Hadoop离线image查看器。

    5.1.13 snapshotDiff

    确定HDFS快照之间的差异。

    5.1.14 version

    打印版本。

    5.2 管理命令

    hadoop集群管理员常用的命令。

    5.2.1 balancer

    运行集群平衡工具。管理员可以简单的按Ctrl-C来停止平衡过程。

    5.2.2 cacheadmin

    HDFS缓存管理。

    5.2.3 crypto

    HDFS透明加密。

    5.2.4 datanode

    运行HDFS datanode。

    5.2.5 dfsadmin

    DFSAdmin命令集用于管理HDFS集群。这些是仅由HDFS管理员使用的命令。以下是一些示例/命令对:

    img

    5.2.6 diskbalancer

    运行磁盘调度程序CLI。

    5.2.7 erasurecode

    运行ErasureCoding CLI。

    5.2.8 haadmin

    在带有NFS的HDFS HA或带有QJM的HDFS HA中使用。

    5.2.9 journalnode

    这个命令启动一个journalnode用于带有QJM的HDFS HA。

    5.2.10 mover

    运行数据迁移实用程序。

    5.2.11 namenode

    运行namenode。以及升级和回滚。

    5.2.12 nfs3

    这个comamnd启动NFS3网关用于HDFS NFS3服务。

    5.2.13 portmap

    这个comamnd启动RPC portmap用于HDFS NFS3服务。

    5.2.14 secondarynamenode

    运行HDFS辅助节点。

    5.2.15 storagepolicies

    列出所有/获取/设置/取消设置存储策略。

    5.2.16 zkfc

    这个命令启动一个Zookeeper故障转移控制器过程与带有QJM的HDFS HA一起使用。

    5.3 调试命令

    有效的帮助管理员调试HDFS问题。这些命令仅适用于高级用户。

    5.3.1verifyMeta

    验证HDFS元数据和块文件。如果指定了块文件,我们将验证元数据文件中的校验和是否与块文件匹配。

    5.3.2 computeMeta

    从块文件计算HDFS元数据。如果指定了块文件,我们将从块文件计算校验和,并将其保存到指定的输出元数据文件。

    注意:使用它是有风险的,如果块文件已损坏,并覆盖它的元文件,它将在HDFS中显示为“正常”,但却无法读取数据。当你100%确定块文件正常的时候才能使用。

    5.3.3 recoverLease

    在指定的路径上恢复租约。路径必须驻留在HDFS文件系统上。默认的重试次数为1。

    6. 扩展阅读

    6.1 档案存储,SSD和内存

    归档存储是将增长的存储容量与计算能力分离的解决方案。具有使较高密度和具有低计算能力的较低成本存储器的节点变得可用,并且可以用作集群中的冷存储器。基于策略,来自热的数据可以被移动到冷。向冷存储中添加更多节点可以增加存储,而与集群中的计算能力无关。

    异构存储和归档存储提供的框架将HDFS架构概括为包括其他种类的存储介质,包括SSD和存储器。用户可以选择将其数据存储在SSD或内存中以获得更好的性能。

    6.1.1 存储类型

    异构存储的第一阶段将datanode存储模型从单个存储(其可以对应于多个物理存储介质)改变为存储的集合,其中每个存储对应于物理存储介质。它还添加了存储类型的概念,DISK和SSD,其中DISK是默认存储类型。

    添加了新的存储类型ARCHIVE,它具有高存储密度(PB级存储),但计算能力很低,用于支持存档存储。

    添加了另一个新的存储类型RAM_DISK,用于支持在内存中写入单个副本文件。

    6.1.2 存储策略

    引入了存储策略的新概念,以便允许根据存储策略将文件存储在不同的存储类型中。

    我们有以下存储策略:

    • Hot:用于存储和计算。一直在使用的数据将保留在此策略中。当块经常被用到时,所有副本都存储在DISK中。
    • Cold:仅适用于有限计算的存储。不再使用的数据或需要归档的数据将从热存储移动到冷存储。当块不经常被用到时,所有副本都存储在ARCHIVE中。
    • Warm:部分热和部分冷的数据。当块热时,其一些副本存储在DISK中,其余的副本存储在ARCHIVE中。
    • All_SSD:用于存储SSD中的所有副本。
    • One_SSD:用于存储SSD中的一个副本。剩余的副本存储在DISK中。
    • Lazy_Persist:用于在内存中写入单个副本的块。副本首先写入RAM_DISK,然后它被持久化在DISK中。

    6.1.3 存储策略解析

    创建文件或目录时,其存储策略未指定。可以使用“storagepolicies -setStoragePolicy”命令指定存储策略。文件或目录的有效存储策略由以下规则解决。

    • 如果使用存储策略指定文件或目录,请返回;
    • 对于未指定的文件或目录,如果它是根目录,请返回默认存储策略。否则,返回其父级的有效存储策略。

    可以通过“storagepolicies -getStoragePolicy”命令检索有效的存储策略。

    6.1.4 Mover新的数据迁移工具

    添加了一个新的数据迁移工具,用于归档数据。该工具类似于Balancer。它定期扫描HDFS中的文件,以检查块布局是否满足存储策略。对于违反存储策略的块,它会将副本移动到不同的存储类型,以满足存储策略要求。

    6.2 升级和回滚

    当在一个已有集群上升级Hadoop时,像其他的软件升级一样,可能会有新的bug或一些会影响到现有应用的非兼容性变更出现。在任何有实际意义的HDSF系统上,丢失数据是不被允许的,更不用说重新搭建启动HDFS了。HDFS允许管理员退回到之前的Hadoop版本,并将集群的状态回滚到升级之前。HDFS在一个时间可以有一个这样的备份。在升级之前,管理员需要用bin/hadoop dfsadmin -finalizeUpgrade命令删除存在的备份文件。下面简单介绍一下一般的升级过程:

    • 升级Hadoop软件之前,请检查是否已经存在一个备份,如果存在,可执行相应操作删除这个备份。通过dfsadmin -upgradeProgress status命令能够知道是否需要对一个集群执行该操作;
    • 停止集群并部署新版本的Hadoop;
    • 使用-upgrade选项运行新的版本(bin/start-dfs.sh -upgrade);
    • 在大多数情况下,集群都能够正常运行。一旦我们认为新的HDFS运行正常(也许经过几天的操作之后),就可以对之执行删除存在的备份文件操作;
    • 如果需要退回到老版本。

    停止集群并且部署老版本的Hadoop。

    在namenode(bin /hdfs namenode -rollback)上运行rollback命令。

    用回滚选项启动集群(bin/start-dfs.h -rollback)。

    当升级到新版本的HDFS时,有必要重命名或删除在新版本的HDFS中保留的任何路径。如果NameNode在升级期间遇到保留路径,它将打印如下错误:

    /.reserved是保留路径,.snapshot是此版本的HDFS中的保留路径组件。请回滚并删除或重命名此路径,或使用-rename Reserved [键值对]选项升级以在升级期间自动重命名这些路径。

    指定-upgrade -renameReserved [可选键值对]使NameNode自动重命名启动期间找到的任何保留路径。例如,要将名为.snapshot的所有路径重命名为.my-snapshot并将.reserved重命名为.my-reserved,用户将指定-upgrade –rename Reserved .snapshot = .my-snapshot,.reserved = .my-reserved。

    如果没有使用-renameReserved指定键值对,NameNode将使用<LAYOUT-VERSION> .UPGRADE_RENAMED。

    这个重命名过程有一些注意事项。如果可能,建议在升级之前先引用hdfs dfsadmin -saveNamespace。这是因为如果编辑日志操作引用自动重命名文件的目标,则可能导致数据不一致。

    6.3 HDFS滚动升级

    HDFS滚动升级允许升级单个HDFS守护进程。例如,可以独立于数据节点升级数据节点。一个namenode可以独立于其他namenode升级。可以独立于datanode和journal节点升级namenode。

    6.3.1 升级

    在Hadoop v2中,HDFS支持高可用性(HA)namenode服务和线路兼容性。这两个功能使升级HDFS成为可能,而不会导致HDFS停机。为了在不停机的情况下升级HDFS集群,必须使用HA设置集群。

    如果在新软件版本中启用了任何新功能,升级后可能无法使用旧软件版本。在这种情况下,升级应通过以下步骤完成:

    • 禁用新功能;
    • 升级集群;
    • 启用新功能。

    请注意,滚动升级仅受Hadoop-2.4.0及更高版本的支持。

    6.3.1.1 无停机升级

    在HA群集中,有两个或更多NameNode(NN),许多DataNodes(DN),一些JournalNodes(JN)和一些ZooKeeperNodes(ZKN)。JNs相对稳定,在大多数情况下升级HDFS时不需要升级。无停机升级仅考虑NN和DN,JN和ZKN不是。升级JN和ZKN可能会导致集群停机。

    6.3.1.2 随着停机时间升级

    对于非HA群集,无法在不停机的情况下升级HDFS,因为需要重新启动namenode。但是,datanode仍然可以滚动方式升级。

    6.3.2 降级和回滚

    当升级版本不受欢迎时,或者在某些情况下,升级失败(由于较新版本中的错误),管理员可以选择将HDFS降级回升级前版本,或者将HDFS回滚到升级前版本,升级前的状态。

    6.3.2.1 降级

    降级将软件恢复到升级前版本,并保留用户数据。假设时间T是滚动升级开始时间,升级通过降级终止。然后,在T之前或之后创建的文件在HDFS中仍然可用。在T之前或之后删除的文件在HDFS中保持删除。

    只有在这两个版本之间不更改namenode布局版本和datanode布局版本时,较新版本才可降级到升级前版本。

    6.3.2.2 回滚

    回滚将软件恢复到升级前版本,但还会将用户数据恢复为升级前状态。假设时间T是滚动升级开始时间,并且通过回滚终止升级。在T之前创建的文件在HDFS中保持可用,但在T之后创建的文件变得不可用。在T之前删除的文件在HDFS中保持删除,但在T之后删除的文件将恢复。

    始终支持从较新版本回滚到预升级版本。然而,它不能以滚动方式完成。它需要集群停机。

    6.4 HDFS配额指南

    6.4.1 概述

    HDFS允许管理员为使用的命名和每个个人的文件夹设置配额。命名配额和空间配额独立操作,但是这两种情况的管理和实现是连接紧密的。

    6.4.2 命名配额

    命名配额是一个在这个文件夹下文件和文件夹的数目。如果超过限额那么文件和文件夹的创建会失败,重命名后命名配额仍然起作用。如果重命名操作违反配额的限制,那么重命名会失败。新创建的目录中没有配额的限制。Long.Max_Value表示最大限额。如果配额为1那么这个文件夹会强制为空。(一个目录也占用自己的配额)。

    配额被持久化在fsimage中,当启动后,如果fsimage 马上违反了配额限制(由于fsimage偷偷的改变),这是会打印警告。设置或删除配额会创建一个空的日志。

    6.4.3 空间配额

    空间配额是设置一个文件夹的大小。如果超过那么块写入会失败。副本也算配额中的一部分。重命名文件夹后配额还是起作用,如果已经违反了配额,那么重命名操作会失败。新创建的文件夹不会有配额的限制,Long.Max_Value可以设置最大的配额。配额设置为0还是运行文件创建,但是不能向文件中写入块。文件夹不使用主机文件系统不计算在空间配额里面,主机文件系统用来记录文件源数据的数据不算在配额中。

    配额被持久化在fsimage中,当启动后,如果fsimage 马上违反了配额限制(由于fsimage会慢慢的改变),这是会打印警告。设置或删除配额会创建一个空的日志。

    6.4.4 存储类型配额

    存储类型配额是对目录中根目录的树中的文件对特定存储类型(SSD,DISK,ARCHIVE)的使用的限制。它在许多方面类似于存储空间配额,但对群集存储空间使用提供细粒度控制。要在目录上设置存储类型配额,必须在目录上配置存储策略,以便允许根据存储策略将文件存储在不同的存储类型中。

    存储类型配额可以与空间配额和名称配额组合,以有效地管理群集存储使用。例如:

    • 对于配置了存储策略的目录,管理员应为资源约束存储类型(如SSD)设置存储类型配额,并为其他存储类型保留配额,并使用限制较少的值或默认无限制总空间配额。HDFS将根据存储策略和总空间配额从两种目标存储类型中扣除配额;
    • 对于未配置存储策略的目录,管理员不应配置存储类型配额。即使特定存储类型不可用(或可用但未正确配置存储类型信息),也可以配置存储类型配额。但是,在这种情况下,建议使用总空间配额,因为存储类型信息对于存储类型配额强制不可用或不准确;
    • DISK上的存储类型配额使用有限,除非DISK不是主要的存储介质。(例如,主要具有ARCHIVE存储的集群)。

    6.5 HDFS短路本地读

    在HDFS中,读取通常通过DataNode。因此,当客户端请求DataNode读取文件时,DataNode从磁盘读取该文件,并通过TCP将数据发送到客户端。所谓的“短路”读取就是绕过DataNode,允许客户端直接读取文件。显然,这仅在客户端与数据位于同一位置的情况下是可能的。短路读数为许多应用提供了实质性的性能提升。

    6.6 HDFS中的集中式缓存管理

    集中式缓存管理在HDFS是一个明确的缓存机制,允许用户指定路径由HDFS进行缓存。NameNode将与在磁盘上具有所需块的DataNode通信,并指示它们在堆外高速缓存中缓存块。

    HDFS中的集中式缓存管理具有许多显着的优点:

    • 显式锁定可防止频繁使用的数据从内存中逐出。当工作集的大小超过主存储器的大小时,这是特别重要的,这对于许多HDFS工作负载是常见的;
    • 由于DataNode缓存由NameNode管理,因此应用程序可以在进行任务放置决策时查询缓存的块位置集合。将任务与缓存的块副本共置可提高读取性能;
    • 当块由DataNode缓存时,客户端可以使用一个新的,更高效的零拷贝读取API。由于缓存数据的校验和验证由DataNode完成,因此客户端在使用此新API时可能会产生基本上为零的开销;
    • 集中式缓存可以提高整体集群内存利用率。当依赖每个DataNode的OS缓冲区缓存时,重复读取一个块将导致该块的所有n个副本都被拉入缓冲区缓存。通过集中式缓存管理,用户可以明确地仅定位n个副本中的m个,从而节省nm内存。

    6.7 HDFS NFS网关

    NFS网关支持NFSv3,并允许将HDFS作为客户端本地文件系统的一部分加载。当前NFS网关支持并启用以下使用模式:

    • 用户可以通过NFSv3客户端兼容操作系统上的本地文件系统浏览HDFS文件系统;
    • 用户可以将文件从HDFS文件系统下载到本地文件系统;
    • 用户可以将文件从本地文件系统直接上传到HDFS文件系统;
    • 用户可以通过挂载点直接将数据流传输到HDFS。支持文件追加,但不支持随机写入。

    NFS网关机器需要相同的东西来运行HDFS客户端,如Hadoop JAR文件,HADOOP_CONF目录。NFS网关可以与DataNode,NameNode或任何HDFS客户端位于同一主机上。

    6.8 HDFS中的扩展属性

    扩展属性(缩写为xattrs)是一种文件系统功能,允许用户应用程序将其他元数据与文件或目录相关联。与系统级inode元数据(如文件权限或修改时间)不同,扩展属性不由系统解释,而是由应用程序用于存储有关inode的附加信息。扩展属性可以用于例如指定纯文本文档的字符编码。

    6.8.1 HDFS扩展属性

    HDFS中的扩展属性是在Linux中扩展属性之后建模的。扩展属性是名称/值对,具有字符串名称和二进制值。Xattrs名称也必须用一个前缀的命名空间。例如,在用户命名空间中名为myXattr的xattr 将被指定为user.myXattr。多个xattrs可以与单个inode关联。

    6.8.2 命名空间和权限

    在HDFS中,有五个有效的命名空间:user,trusted,system,security和raw。这些命名空间中的每一个都有不同的访问限制。

    用户的命名空间通常是由客户端应用程序使用的命名空间。在用户命名空间中对扩展属性的访问由相应的文件权限控制。

    这个命名空间通常不能通过用户空间方法访问。这个xattr只能对文件设置,并且会阻止超级用户读取文件的内容。超级用户仍然可以读取和修改文件元数据,例如所有者,权限等。此xattr可以由任何用户设置和访问,这个xattr也是一次写,一旦设置就不能删除。此xattr不允许设置值。

    6.9 HDFS中的透明加密

    6.9.1 概述

    Hadoop Key Management Server(KMS)是一个基于HadoopKeyProvider API编写的密钥管理服务器。他提供了一个client和一个server组件,client和server之间基于HTTP协议使用REST API通信。Client是一个KeyProvider的实现,使用KMS HTTP REST API与KMS交互。KMS和它的client有内置的安全机制,支持HTTP SPNEGO Kerberos认证和HTTPS安全传输。KMS是一个Java Web应用程序,运行在与Hadoop发行版绑定在一起的预先配置好的Tomcat服务器上。

    HDFS 实现透明,端到端加密。配置完成后,用户往hdfs上存储数据的时候,无需用户做任何程序代码的更改(意思就是调用KeyProvider API ,用于在数据存入到HDFS上面的时候进行数据加密,解密的过程一样)。这意味着数据加密和解密由客户端完成的。HDFS 不会存储或访问未加密的数据或数据加密密钥(由kms管理)。

    6.9.2 背景介绍

    越来越多的用户关注安全问题,都在寻找一种有效的,方便的加密方式。hadoop提供了几种不同形式的加密,最底层的加密,加密所有节点数据,有效地保护了数据,但是却缺乏更细粒度的加密;

    kms 透明加密可以做到更细粒度的加密;

    加密可以在不同的层级进行,包括软件/软件堆栈,选择不同的加密层级各有优缺点:

    • 应用程序级加密。这是最安全、最灵活的方法。该应用程序可以极大地控制加密的内容,并可以精确地反映用户的需求。但是,编写应用程序是很难的。对于不支持加密的现有应用程序的客户,这也不是一个选择;
    • 数据库级加密。与其属性相似的应用级加密。大多数数据库供应商提供某种形式的加密。但是,可能会出现性能问题。一个例子是索引不能被加密;
    • 文件系统级进行加密。此选项提供高性能,应用程序透明度,通常易于部署。但是,它无法建模一些应用程序级策略。例如,多租户应用程序可能希望基于最终用户进行加密。数据库可能需要对单个文件中存储的每个列进行不同的加密设置;
    • 磁盘级别加密。容易部署和高性能,但也很不灵活。

    HDFS级加密适用于此堆栈中的数据库级和文件系统级加密。这有很大的积极作用。HDFS加密能够提供良好的性能,现有的Hadoop应用程序能够透明地运行加密数据。在制定政策决策时,HDFS还具有比传统文件系统更多的上下文。

    HDFS级别的加密还可以防止在文件系统级别及以下的攻击(所谓的“操作系统级攻击”)。操作系统和磁盘只与加密的字节进行交互,因为数据已被HDFS加密。

    6.10 HDFS支持多宿主网络

    在多宿主网络中,集群节点连接到多个网络接口。这样做可能有多种原因。

    • 安全性:安全性要求可能决定集群内业务被限制在与用于将数据传入和传出集群的网络不同的网络中。
    • 性能:集群内流量可能使用一个或多个高带宽互连,如光纤通道,Infiniband或10GbE。
    • 故障转移/冗余:节点可能有多个网络适配器连接到单个网络以处理网络适配器故障。

    6.11 HDFS中的内存存储支持

    HDFS支持写入由数据节点管理的堆外存储器。数据节点会将内存中的数据异步刷入磁盘,从而从性能要求比较高的IO路径中去掉磁盘IO和校验和计算,因此我们称这种写入为Lazy Persist写入。HDFS为Lazy Persist 写入提供持久性保证。在将副本保留到磁盘之前,在节点重新启动的情况下,可能会发生数据丢失。应用程序可以选择使用Lazy Persist写入来折衷一些持久性保证,以减少延迟。

    此功能从Apache Hadoop 2.6.0开始提供。

    img

    目标使用案例是将受益于以低延迟写入相对少量的数据(从几GB到几十GB,取决于可用存储器)的应用。内存存储用于在集群中运行并与HDFS数据节点并置的应用程序。我们已经观察到,网络复制的延迟开销抵消了写入内存的好处。

    使用Lazy Persist 写入的应用程序将继续工作,如果内存不足或未配置,则回到DISK存储。

    6.12 HDFS纠删码

    6.12.1 概述

    随着大数据技术的发展,HDFS作为Hadoop的核心模块之一得到了广泛的应用。为了系统的可靠性,HDFS通过复制来实现这种机制。但在HDFS中每一份数据都有两个副本,这也使得存储利用率仅为1/3,每TB数据都需要占用3TB的存储空间。随着数据量的增长,复制的代价也变得越来越明显:传统的3份复制相当于增加了200%的存储开销,给存储空间和网络带宽带来了很大的压力。因此,在保证可靠性的前提下如何提高存储利用率已成为当前HDFS应用的主要问题之一。针对这些问题,英特尔和Cloudera开始引入纠删码(Erasure Coding,EC)技术,在保证数据可靠性的同时大幅降低存储开销。

    Erasure coding纠删码技术简称EC,是一种数据保护技术。最早用于通信行业中数据传输中的数据恢复,是一种编码容错技术。他通过在原始数据中加入新的校验数据,使得各个部分的数据产生关联性。在一定范围的数据出错情况下,通过纠删码技术都可以进行恢复。

    6.12.2 纠删码(Erasure Code)与 Reed Solomon码

    在存储系统中,纠删码技术主要是通过利用纠删码算法将原始的数据进行编码得到校验,并将数据和校验一并存储起来,以达到容错的目的。其基本思想是将k块原始的数据元素通过一定的编码计算,得到m块校验元素。对于这k+m块元素,当其中任意的m块元素出错(包括数据和校验出错),均可以通过对应的重构算法恢复出原来的k块数据。生成校验的过程被成为编码(encoding),恢复丢失数据块的过程被称为解码(decoding)。

    Reed-Solomon(RS)码是存储系统较为常用的一种纠删码,它有两个参数k和m,记为RS(k,m)。如图1所示,k个数据块组成一个向量被乘上一个生成矩阵(Generator Matrix)GT从而得到一个码字(codeword)向量,该向量由k个数据块和m个校验块构成。如果一个数据块丢失,可以用(GT)-1乘以码字向量来恢复出丢失的数据块。RS(k,m)最多可容忍m个块(包括数据块和校验块)丢失。

    img

    6.12.3 块组(BlockGroup)

    对HDFS的一个普通文件来说,构成它的基本单位是块。对于EC模式下的文件,构成它的基本单位为块组。块组由一定数目的数据块加上生成的校验块放一起构成。以RS(6,3)为例,每一个块组包含1-6个数据块,以及3个校验块。进行EC编码的前提是每个块的长度一致。如果不一致,则应填充0。图2给出三种不同类型的块组及其编码。

    img

    6.12.4 连续布局(Contiguous Layout)VS条形布局(Striping Layout)

    数据被依次写入一个块中,一个块写满之后再写入下一个块,数据的这种分布方式被称为连续布局。在一些分布式文件系统如QFS和Ceph中,广泛使用另外一种布局:条形布局。条(stripe)是由若干个相同大小单元(cell)构成的序列。在条形布局下,数据被依次写入条的各个单元中,当条被写满之后就写入下一个条,一个条的不同单元位于不同的数据块中。

    img

    6.12.5 Erasure Coding技术的优劣势

    6.12.5.1 优势

    纠删码技术作为一门数据保护技术,自然有许多的优势,首先可以解决的就是目前分布式系统,云计算中采用副本来防止数据的丢失。副本机制确实可以解决数据丢失的问题,但是翻倍的数据存储空间也必然要被消耗,这一点却是非常致命的。EC技术的运用就可以直接解决这个问题。

    6.12.5.2 劣势

    EC技术的优势确实明显,但是他的使用也是需要一些代价的,一旦数据需要恢复,他会造成2大资源的消耗:

    • 网络带宽的消耗,因为数据恢复需要去读其他的数据块和校验块;
    • 进行编码,解码计算需要消耗CPU资源;
    • 概况来讲一句话,就是既耗网络又耗CPU,看来代价也不小。所以这么来看,将此用于线上服务可能会觉得不够稳定,所以最好的选择是用于冷数据集群,有下面2点原因可以支持这种选择;
    • 冷数据集群往往有大量的长期没有被访问的数据,体量确实很大,采用EC技术,可以大大减少副本数;
    • 冷数据集群基本稳定,耗资源量少,所以一旦进行数据恢复,将不会对集群造成大的影响。

    出于上述2种原因,冷数据集群无非是一个很好的选择。

    6.13合成负载生成器

    合成负载生成器(SLG)是用于在不同客户端负载下测试NameNode行为的工具。用户可以通过指定读取和写入的概率来生成读取、写入和列表请求的不同混合。用户通过调整工作线程的数量和操作之间的延迟的参数来控制负载的强度。当负载生成器正在运行时,用户可以配置和监视NameNode的运行。当Load Generator退出时,它会打印一些NameNode统计信息,如每种操作的平均执行时间和NameNode吞吐量。


 

Copyright © 2018 bbs.dian.org.cn All rights reserved.

与 Dian 的连接断开,我们正在尝试重连,请耐心等待