5.2.1.1.2-HDFS-调研

优质
小牛编辑
126浏览
2023-12-01

1.1 Hadoop简介

2005年,Lucene 的创始人 Doug Cutting 主持开发完成了首款支持海量数据存储计算的分布式开源框架—Hadoop。Hadoop的初始定位是服务于大量的具有廉价硬件设备的服务器,且对存储的数据具有较高的容错性,随着 Hadoop功能的逐步完善,目前 Hadoop已经晋升为 Apache的顶级项目。Hadoop框架主要包括 Hadoop分布式文件系统(HDFS),MapReduce编程模型,以及其他相关衍生组件。 其中,HDFS是一个基于普通 Linux文件系统的可扩展集群文件系统,具有很高的数据容错功能。MapReduce是一个用于处理海量数据的并发编程模型,采用分而治之的思想将海量数据划分到多台机器上用相同的模式进行处理,然后汇总处理结果;这种编程模式充分挖掘了集群的计算能力,具有很高的应用价值。另外,Hadoop生态系统还包括一些库和工具,它们在一起提供了基于分布式文件系统的功能抽象。 Hadoop的出现最早始于 Google 公司对他们内部相关技术的公开,即关于GFS、BigTable、MapReduce的三篇论文的发布。目前 Hadoop已经被许多公司广泛使用,国外的主流互联网企业基本都使用了Hadoop,包括Facebook、IBM、Yahoo,国内的百度、阿里、腾讯、中国移动等, 许多公司多年来还对Hadoop进行了深度定制,以适应自身业务的特点。 尽管 Hadoop已经成为了行业内的大数据标准方案,但其仍然有着许多的局限和不足。因为 Hadoop的设计初衷是为了满足大文件的顺序读写需求,因此它对文件的随机读写操作支持的并不是很充分,读写效率不高。MapReduce编程模型最初是为了解决线下海量数据的处理问题,因此该编程模型并不适用于线上业务的实时性要求。从整体上看,Hadoop平台主要是面向于对实时性要求并不高的业务场景,且更多的是为了解决海量离线数据的处理。

1.2 HDFS简介

Hadoop分布式文件系统(HDFS)是 Hadoop 的核心组件之一,它是海量数据存储与计算的基础,无论是 Hadoop 本身还是基于其的衍生组件,如HBase、Hive 等都是将数据存储在 HDFS 中,唯一的不同是上层组件修改了数据在HDFS中的存储格式。

1.2.1 HDFS设计目标

(1)在HDFS的设计过程中,硬件设备的失效被认为是常态事件,所以 HDFS 内部功能嵌入了数据错误检测、硬件故障冗余、数据自动恢复等机制。 (2)HDFS 是面向大文件设计的,采用流式输入输出来处理数据;一个大文件在HDFS中会被拆分成几十乃至几百 MB的块,数据在系统的存储以块为单位,副本机制也是建立在块之上。在 HDFS中,块大小可以根据应用场景的特定来动态修改。块越大,越有利于大文件的流式读取;块越小,越有利于分布式文件系统空间利用率的提高,所以需要根据实际情况来选择块大小。流式输入输出可以等效为对文件的顺序读写操作,HDFS不支持对文件的随机读写,所以它的应用场景受限很多。 (3)文件在 HDFS 中被假设为只需要一次创建、写入,正常情况下,HDFS中的文件不会被修改,这种设计思想是为了简化系统的设计复杂度,也可以最大程度的提高系统的吞吐量。一般情况下,存储在 HDFS中的块比较大,而在现实集群环境下,网络带宽是相对紧缺的资源,所以 HDFS的设计目标之一是将计算方法分发到拥有相应数据副本的节点上,而不是将数据传送至拥有计算方法的节点;这可以极大地降低网络的开销。另外,文件块副本在集群中是独立于机架分散放置的,使得HDFS可以实现本地副本优先读写这一目标。

1.2.3 HDFS容错机制

  • (1) 备份节点(Standby NameNode) 为了避免名称节点的单点故障带来的灾难性后果,Hadoop后来的版本中增加了名称节点的备份节点;在活动名称节点(Active NameNode)正常提供服务的时候,备份节点只是简单的将名称节点上的文件系统元数据进行备份,一旦名称节点由于故障不能提供服务,备份节点就会接替名称节点继续提供服务;这样就避免了整个集群陷入停服的灾难性后果。 元数据备份的过程,备用名称节点(Standby NameNode)会读取FSImage文件中的内容,并且每隔一段时间就会把活动名称节点(Active NameNode)写入edit log中的记录读取出来,这样备用名称节点的NameNode进程中一直保存着HDFS文件系统的最新状况命名空间。当达到checkpoint条件的某一个时,就会直接将该信息写入一个新的FSImage文件中,然后通过HTTP传输给活动名称节点。
  • (2)快照 HDFS 还提供了快照系统(Snapshot)的容错机制;它的主要思想是每隔固定的时间对文件系统的当前状态做一个整体的复制并保存下来;如果文件系统在某个时刻出现了故障,就可以找到离故障时间最近的一次快照,并还原出快照中所保存的当时的文件系统状态,但是会丢失执行快照到系统故障这段时间的文件操作信息;文件系统快照的频率可以动态设置,快照频率越高,文件系统恢复后丢失的数据就越少;但是需要指出的是,快照对系统的资源消耗较大,会在较大程度上干扰分布式文件系统的正常工作,所以应该谨慎调节。 综合来看,系统快照已经最大程度地避免文件系统恢复后的数据丢失。HDFS快照是文件系统在某个时刻的只读副本。快照可以是文件系统的一个子树,也可以是整个文件系统。快照的一些通用用途包含数据备份,出错保护和容灾恢复。对于数据误删,HDFS提供了回收站功能[4]。
  • (3)安全模式 安全模式(SafeMode):HDFS文件系统的只读模式,实际上用户可以通过命令选择进入、离开安全模式。在名称节点启动的过程中,名称节点将会进入安全模式,等待数据节点上报数据块与数据节点对应关系,只有大部分数据上报副本达到安全模式所设置的阈值要求,安全模式自然就会退出,NameNode正式启动完毕。 (4)NameNode联邦 文件数量过多时,名称节点成为性能瓶颈,所以引入了HDFS联邦(Federation)的机制[4],允许多台机器共同管理命名空间,每台主机管理一部分命名空间,即命名空间卷(namespace volumn)。命名空间之间互相独立,互不通信。例如一台主机管理/user目录,另一台主机管理/share目录。一台名称节点宕机也不会影响保存其他名称节点上的目录的使用[5]。

    1.2.4 HDFS数据存储机制

  • (1)数据块机制 在 Hadoop分布式文件系统中,超过预设定块大小的文件都会被切分成多个文件块存储,文件块大小是可配置的,默认的大小为128MB。在一般情况下,一个文件的大小不会刚刚是块大小的整数倍,最后一个块中的数据没有写满,会存在空间闲置,称之为块内碎片。为了降低数据读取的整体延时,HDFS将块大小设置的比较大,这样一来,文件块的寻找时间占整个数据读取时间的比重就很小,数据读取的耗时主要就取决于磁盘带宽和网络带宽。HDFS中处理文件数据是以块为单位进行的,这种存储机制可以带来多个存储优势。由于 Hadoop的设计初衷是运行在可靠性不高的普通服务器上,底层的硬件故障频率非常高,以文件块为粒度执行文件操作时,当硬件发生故障或数据传输发生错误,系统不需要恢复完整的文件数据,只需要恢复相应的文件块数据。可通过hdfs fsck查看数据块副本状态。
  • (2)副本机制 Hadoop分布式文件系统的数据可靠性保证主要是靠它的副本机制。在正常情况下,文件的每一个块数据有多个副本。默认三副本的放置策略是在本机架的不同机器中放置二份,在另外一台机架中放置一份,这种策略称之为机架感知技术;它可以将对同一个文件块的请求分散到不同的机器上,在提高数据可靠性的同时增加系统的吞吐量(读取效率)。 在 HDFS中,文件的创建过程并不是在分布式文件系统中及时可见的;客户端在新建文件时,会在本地创建一个临时文件并开始累积文件数据,当累积的文件数据达到了系统设定的块大小或用户关闭了创建的文件,此时,客户端才会将创建文件的请求发送给 Hadoop的名称节点,名称节点接收到创建请求后,会将客户端发送过来的新文件的属性信息根据一定的策略插入到自己的文件系统目录树中,并在分布式系统中检索可用的存储空间,找到后就会将数据节点的信息发送给客户端,由客户端直接与数据节点发起连接请求并写入文件数据。至此,客户端将数据块的第一个副本写入了数据节点;如果系统的副本数大于 1,其余的副本由数据节点根据名称节点发送过来的指示,采用管道的形式写入其他的数据节点。位于流水线最后位置的节点在收到数据并正确存储后会向前一个数据节点发送确认信息,前一个节点在自己正确存储数据并收到后一个节点的确认信息后向第一个数据节点发送确认信息,第一个数据节点在自己正确存储数据并收到后一个节点发送的确认信息后向客户端发送数据写入成功的确认,客户端在收到确认信息后继续写入后续的数据,直至所有数据全部写完。
  • (3)提高读写效率的存储机制 HDFS是一款基于磁盘的分布式文件系统,其读写性能不如基于内存的文件系统如Alluxio,但如今全面使用内存进行存储是不现实的。一方面内存空间有限,另一方面内存数据在机器重启后丢失。但HDFS就其提升读写效率也提供了两种常见的解决方案:集中式缓存和多介质分级存储。

    2. 架构

    HDFS 架构.PNG Hadoop分布式文件系统采用经典的主从架构体系,集群结构包含一个名称节点(NameNode)和多个数据节点(DataNode)[1]。集群架构如图1所示。 图1 HDFS体系结构示意图

    2.1 名称节点(NameNode)

    名称节点是存储集群最重要的角色,它的主要功能是负责维护整个文件系统的命名空间,以及数据块和数据节点的映射关系。命名空间包括文件系统目录树,文件所在目录信息、文件属性以及文件数据块索引,这些信息以命名空间镜像文件和编辑日志文件永久保存在名称节点命名空间镜像(fsImage)文件中。而数据块和数据节点的映射关系信息,则是数据节点启动后定期汇报过来的,动态地存在名称节点的内存中。 fsImage文件时不会随着命名空间的改变时刻更新,对文件系统的操作保存在编辑日志(editLog)文件中。系统在四种情况下进checkpoint操作,合并生成新的fsImage和editLog文件:名称节点重启;手动执行checkpoint操作;距离上一次checkpoint操作超过dfs.namenode.checkpoint.preiod设置的阈值;上一次checkpoint操作后操作数超过dfs.namenode.checkpoint.txns设置的阈值。 文件在 HDFS 中是以文件块的形式存储,超过块大小的文件会被划分成多个文件块,并将这些文件块的副本分散存储在集群的数据节点上;每一个文件对应着一个或多个文件块,想要查找某个具体文件的数据,需要知道该文件的数据块都存储在哪些机器上;名称节点记录着每个块的所在数据节点的信息,这些映射信息是在名称节点启动的时候由各个数据节点汇报过来的,并不会被名称节点持久化在磁盘中,因为文件块信息伴随着文件的操作是动态变化的。 在存储集群运行过程中,由于硬件故障或者网络问题,造成文件块副本丢失或者错误,名称节点在检测到后需要对错误或丢失的文件块进行恢复,例如通过其他正常副本在别的数据节点上重写一份数据;一种极端的情况是,某个数据节点故障后,该节点上的所有文件副本都需要重新在其他数据节点上恢复。保证文件系统中所有文件块副本数符合要求以及副本数据的正确性也是名称节点的一个重要功能。

    2.2 数据节点(DataNode)

    数据节点的主要功能是按照名称节点的调度存储实际的文件块数据,响应客户端的读写请求,并用心跳机制与名称节点保持连接。 数据节点在启动的时候会完整检查自己存储和缓存的文件块信息,并将这些信息汇报给名称节点以供其建立文件块和数据节点的映射信息;同时,数据节点还会接受名称节点的命令,创建、复制或者删除具体的文件块;客户端从名称节点获取到具体的文件块所在的位置后,会向该数据节点请求文件块数据,从这点来说,数据节点还会和客户端进行数据交互。

    2.3 HDFS客户端

    HDFS 客户端是以 API 的形式提供给用户使用,用户通过调用 HDFS 的API来实现自己的业务功能,并将代码提交给集群执行。HDFS的客户端 API的形式包括 Java API、Thrift接口、C API、用户空间文件系统(Filesystem in Userspace)、命令行等。本文第四章主要介绍最常用的两种接口的使用: Java API和命令行。

参考资料