高可用性的HDFS:Hadoop分布式文件系统深度实践(光盘内容另行下载,地址见书封底)(txt+pdf+epub+mobi电子书下载)


发布时间:2020-06-09 08:20:22

点击下载

作者:文艾,王磊

出版社:清华大学出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

高可用性的HDFS:Hadoop分布式文件系统深度实践(光盘内容另行下载,地址见书封底)

高可用性的HDFS:Hadoop分布式文件系统深度实践(光盘内容另行下载,地址见书封底)试读:

版权信息书名:高可用性的HDFS:Hadoop分布式文件系统深度实践(无赠送光盘)作者:文艾,王磊排版:清茉出版社:清华大学出版社出版时间:2012-05-01ISBN:9787302282587本书由清华大学出版社有限公司授权北京当当科文电子商务有限公司制作与发行。— · 版权所有 侵权必究 · —前 言

Hadoop是目前主流的开源云计算系统,它实现了一个高可扩展的分布式文件系统——HDFS(Hadoop Distributed File System),HDFS作为Hadoop底层基础设施,为云计算提供高可靠、高性能的存储服务。HDFS在很大程度上借鉴了Google GFS文件系统的设计思想,具有高度容错、支持大数据集等诸多特性。这些特性曾让我们欢欣鼓舞,一度以为HDFS是一个可以解决数据密集型应用的海量数据存储难题的完美方案。随着研究的深入,我们在不断叹服HDFS设计构思巧妙的同时,也深深地认识到仅有以上的特性还不足以构建一个实用的分布式文件系统,还需要一些其他特性进行支撑,高可用性则是其中最为关键的一点。

高可用性是指系统正常服务时间所占的百分比,它是衡量系统对外正常服务能力的重要指标。对于HDFS来说,每一份数据可以有多个副本,因此文件数据的可靠性可以由副本来解决。然而,对于元数据管理来说,只有一个节点NameNode,它的好坏直接决定了HDFS能否正常服务,因此NameNode的高可用性决定了整个HDFS系统的高可用性。不同应用对HDFS高可用性有不同要求,目前Hadoop自身包括其他一些开源组织提供了一些相应的高可用性机制以满足不同的需要,如Backup Node方案以及AvatarNode方案等。

根据我们的实践经验,在使用以上方案解决实际问题时,需要具备以下几点基础:

· 首先是对NameNode元数据机制有较深的理解和把握;

· 其次要对各种解决方案的运行机制及使用方法有个全面掌握;

· 再次就是要有较强的实践操作经验。

然而,就现实情况而言,要在以上任何一点取得一点进展都需要付出相当大的努力,回顾我们的团队在接触HDFS的高可用性之初,由于资料和经验的匮乏,每掌握一个知识点,都需经历资料查找、邮件列表搜索、邮件请教、代码查看、实验验证等多个环节,其间的付出可想而知,正是基于这点,我们也深切地感觉有必要将我们前期的经验和心得与大家分享,姑且也算做是我们团队对于开源软件事业的一点小小的回馈吧。本书内容

本书一共8章,分为4个部分。

其中第1部分为第1章,主要介绍当前HDFS主流的HA方案以及相关概念,使读者能够有一个宏观上的认识,同时通过方案的比较,遴选出3种具有代表性的HA方案。

第2部分为第2章,围绕HDFS HA的重点关注对象元数据,对内存元数据结构、磁盘元数据文件、文件系统格式化场景以及元数据在HA中的应用场景进行了深入剖析。

第3部一共5章(3、4、5、6、7),主要介绍3种经典的HA解决方案:Hadoop元数据备份方案、BackupNode方案以及AvatarNode方案,从代码入手,分别从运行机制、使用方法等方面进行说明,每种方案都有详细的使用说明,便于读者掌握。

第4部分为第8章,介绍目前最新HA解决方案Cloudrea HA NameNode。适合读者

如果您是一位Hadoop集群管理维护人员,请阅读本书,它将向您展示当前主流的HDFS HA解决方案,通过文字说明这些方案的实现机制和操作细节,使您能够在最短的时间内消化和吸收这些技术,您可以根据自己的需要选择和部署实施最合适的HA方案。

如果您是一位Hadoop应用开发者,请阅读本书,您将会在此找到如何结合HDFS的HA,编写出更为健壮的应用程序。

如果您是一位分布式文件系统研发人员,请阅读本书,它将向您深入剖析HDFS这一最有影响力的开源云计算分布式存储系统的各种HA方案及其实现机制。

如果您是一位云计算技术的爱好者,请阅读本书,本书会从零开始,一步一步地带您掌握云计算相关技术,并加深概念的理解,为您日后深入接触云计算技术打下基础。

本书由文艾和王磊共同编著而成。文艾负责总体设计、内容把握以及写作组织,独立完成第1、2、3、8章,并与王磊共同完成第4、5、6、7制作。

感谢中国电子学会云计算专家委员会专家刘鹏教授的大力支持;感谢我的家人,你们是我奋斗前进的最大动力;

最后,希望大家从书中找到需要的东西。

时间紧,任务急,错误在所难免,敬请各位批评指正。请发送邮件到hdfsha@126.com。第1章HDFS HA及解决方案【1】HDFS(Hadoop Distributed File System)即Hadoop分布式文件系统,它为Hadoop这个分布式计算框架提供高性能、高可靠、高可扩展的存储服务。1.1 HDFS系统架构

HDFS的系统架构如图1.1所示,它是一个典型的主/从架构,包括一个NameNode节点(主节点)和多个DataNode节点(从节点),并提供应用程序访问接口。NameNode是整个文件系统的管理节点,它负责文件系统名字空间(Namespace)的管理与维护,同时负责客户端文件操作的控制以及具体存储任务的管理与分配;DataNode提供真实文件数据的存储服务。图1.1 HDFS系统架构

HDFS有两种数据:文件数据和元数据。1.文件数据

文件数据是指用户保存在HDFS上的文件的具体内容,HDFS将用户保存的文件按照固定大小(用户可设置,通常是64MB)进行分块(每一块简称为一个Block),保存在各个DataNode上,每一个块可能会有多个副本(Replica),具体个数可以由用户指定(通常是3个),相同块对应的副本通常保存在不同的DataNode上,通过副本机制,可以有效保证文件数据的可靠性。2.元数据

所谓元数据(Metadata)是指数据的数据,HDFS与传统的文件系统一样,提供了一个分级的文件组织形式,维护这个文件系统所需的信息(除了文件的真实内容)就称之为HDFS的元数据。

元数据由NameNode进行维护和管理,NameNode在启动时,会从磁盘加载元数据文件到内存,并且等待Data Node上报其他元数据信息,形成最终的元数据结构。由于NameNode是单节点,一旦NameNode无法正常服务,将导致整个HDFS无法正常服务。1.2 HA定义

HA的英文全称是High Availability,中文翻译为高可用性。什么是HA?HA与我们平时常说的高可靠性又有什么关系,下面我们一起来看下HA的定义。

HA的定义为系统对外正常提供服务时间的百分比。具体来说,【2】HDFS的可靠性可用平均无故障时间(MTTF)来度量,即HDFS正常服务的平均运行时间,HDFS的可维护性用平均维修时间【2】(MTTR)来度量,即HDFS从不能正常服务到重新正常服务所需要的平均维修时间。因此HDFS的HA可精确定义为:*MTTF/(MTTF+MTTR)100%

由上面的定义我们可以很清楚地将HA与高可靠性区分开来,高可靠性更多的是对于系统自身而言,它是系统可靠程度的一个指标。而HA则更多地是从系统对外的角度来说的,除了包含系统正常工作的能力,它还强调系统中止服务后迅速恢复的能力:一个可靠性很高的系统,如果其中止服务后,修复时间很长,那么它的可用性也不会很高,而一个可靠性不是特别高的系统,如果发生中止服务后,可迅速恢复,那么其可用性也可能会很高。因此只有HA才能准确度量系统对外正常服务的能力。

HDFS HA的应用场景有很多,我们可以从正常和异常两种情况来分析HDFS对外无法正常服务的情景:

■ 首先是正常使用情况,最常见的应用场景就是NameNode节点软、硬件的升级与维护,由于NameNode只有一个,当NameNode节点软、硬件的升级与维护操作需要NameNode进行重启时,HDFS将无法服务。

■ 其次是异常情况,常见的场景有:用户的误操作导致NameNode系统崩溃或HDFS发生故障、或者是硬件故障等。在实际使用过程中,软硬件维护、软件故障、错误操作等因素是造成HDFS无法提供正常服务的主要原因,而大家普遍关注的硬件故障并不是主要原因。

雅虎的数据表明:在雅虎运行的15个集群中,三年时间内,只有3次NameNode的故障与硬件问题有关。

此外,由于HDFS处于Hadoop的底层,上层的其他分布式处理框架如Mapreduce、HBase、Hive、Pig等都依赖于HDFS提供的基础服务,因此HDFS的HA将对这些分布式处理框架的HA构成直接影响,并最终影响到最上层分布式应用的HA。因此对于一个实用的系统来说,在大多数情况下都需要考虑HDFS的HA问题。1.3 HDFS HA原因分析及应对措施

根据定义,影响HDFS HA的因素从可靠性和可维护性两方面进行分析。1.3.1 可靠性

我们知道,HDFS由NameNode和Data Node两类节点组成,由于NameNode只有1个,且负责整个HDFS文件系统的管理和控制,因此当NameNode不能提供正常服务时,会直接导致HDFS不能对外正常服务,因此NameNode的可靠性是影响HDFS可靠性的重要因素。

由于NameNode只有一个,它的正常运行与否直接决定了HDFS能否正常服务,因此它也就成为了HDFS系统的一个单一故障点(single point of failure——SPOF),DataNode负责存储真实文件数据,每个文件可以指定副本个数,因此同一个文件可在多个DataNode上进行存储,当有DataNode发生故障时,客户端可以访问其他DataNode上的副本,因此DataNode发生故障并不会影响HDFS对外正常服务。1.3.2 可维护性

当NameNode不能正常服务时,通常需要重新启动NameNode来恢复服务,NameNode启动时需要加载磁盘上的元数据文件:如果此时元数据没有损坏,那么直接启动NameNode就可以恢复HDFS对外正常服务;如果元数据损坏,将导致NameNode无法启动,无法再对外正常服务,也就是说平均维护时间是无限大。

因此元数据的可靠性决定了HDFS的可维护时间。当DataNode无法正常工作时,HDFS会自动启动该DataNode上所有数据的复制任务,将丢失的数据重新分布到其他DataNode上,因此DataNode并不影响HDFS的可维护性。

综上所述,HDFS的HA主要由NameNode的HA决定,NameNode的可靠性主要取决于自身计算机硬件系统的可靠性、系统软件以及HDFS软件的可靠性;NameNode的可维护性则取决于元数据的可靠性以及NameNode服务恢复时间。1.4 现有HDFS HA解决方案

HDFS的HA的解决方案,主要是从使用者的角度出发,提高元数据的可靠性,减少NameNode服务恢复时间。提高元数据的可靠性措施主要是对元数据进行备份,HDFS自身就具有多种机制来确保元数据的可靠性。

减少NameNode服务恢复时间的措施有两种思路:

■ 第1种基于NameNode重启恢复服务的方式,对NameNode自身的启动过程进行分析,优化加载过程,减少启动时间;

■ 第2种则是启动一个NameNode的热备(Warm standby)节点,当主节点不能正常服务时,由热备节点进行接替,此时主备切换时间成为服务恢复时间。

从效率上分析,第1种思路尽管进行了优化,但NameNode的启动时间仍受文件系统规模的限制,第2种则突破了这种限制。

现有比较成熟的HA解决方案有:

■ Hadoop的元数据备份方案【3】

■ Hadoop的Secondary NameNode方案【4】

■ Hadoop的Checkpoint Node方案【5】

■ Hadoop的Backup Node方案【6】

■ DRDB方案

■ Facebook的Avatarnode方案

下面将依次介绍。1.4.1 Hadoop的元数据备份方案

该方案利用Hadoop自身的Failover措施(通过配置dfs.name.dir),NameNode可以将元数据信息保存到多个目录。通常的做法,选择一个本地目录、一个远程目录(通过NFS进行共享),当NameNode发生故障时,可以启动备用机器的NameNode,加载远程目录中的元数据信息,提供服务。优点

■ Hadoop自带机制,成熟可靠,使用简单方便,无需开发,配置即可。

■ 元数据有多个备份,可有效保证元数据的可靠性,并且内容保持最新状态。

■ 元数据需要同步写入多个备份目录,效率低于单个NameNode。缺点

■ 该方案主要是解决元数据保存的可靠性问题,但没有做到热备,HDFS恢复服务时,需要重新启动NameNode,恢复时间与文件系统规模成正比。

■ NFS共享的可靠性问题,如果配置的多个目录中有任何一个目录的保存因为异常而阻塞,将会导致整个HDFS的操作阻塞,无法对外提供正常服务。1.4.2 Hadoop的Secondary NameNode方案

该方案启动一个Secondary NameNode节点,该节点定期从NameNode节点上下载元数据信息(元数据镜像fsimage和元数据库操作日志edits),然后将fsimage和edits进行合并,生成新的fsimage(该fsimage就是Secondary NameNode下载时刻的元数据的Checkpoint),在本地保存,并将其推送到NameNode,同时重置NameNode上的edits。优点

■ Hadoop自带机制,成熟可靠,使用简单方便,无需开发,配置即可。

■ Secondaryary NameNode定期做Checkpoint,可保证各个Checkpoint阶段的元数据的可靠性,同时,进行fsimage与edits的合并,可以有效限制edits的大小,防止其无限制增长。缺点

■ 没有做到热备,当NameNode无法提供服务时,需要重启NameNode,服务恢复时间与文件系统规模大小成正比。

■ Secondary NameNode保存的只是Checkpoint时刻的元数据,因此,一旦NameNode上的元数据损坏,通过Checkpoint恢复的元数据并不是HDFS此刻的最新数据,存在一致性问题。1.4.3 Hadoop的Checkpoint Node方案

Checkpoint Node方案与Secondary NameNode的原理基本相同,只是实现方式不同。该方案利用Hadoop的Checkpoint机制进行备份,配置一个Checkpoint Node。该节点会定期从Primary NameNode中下载元数据信息(fsimage+edits),将edits与fsimage进行合并,在本地形成最新的Checkpoint,并上传到Primary NameNode进行更新。

当NameNode发生故障时,极端情况下(NameNode彻底无法恢复),可以在备用节点上启动一个NameNode,读取Checkpoint信息,提供服务。优点

■ 使用简单方便、无需开发、配置即可。

■ 元数据有多个备份。缺点

■ 没有做到热备、备份节点切换时间长。

■ Checkpoint Node所做的备份,只是最后一次Check时的元数据信息,并不是发生故障时最新的元数据信息,有可能造成数据的不一致。1.4.4 Hadoop的Backup Node方案

利用新版本Hadoop自身的Failover措施,配置一个Backup Node,Backup Node在内存和本地磁盘均保存了HDFS系统最新的名字空间元数据信息。如果NameNode发生故障,可用使用Backup Node中最新的元数据信息。优点

■ 简单方便、无需开发、配置即可使用。

■ Backup Node的内存中对当前最新元数据信息进行了备份(Namespace),避免了通过NFS挂载进行备份所带来的风险。

■ Backup Node可以直接利用内存中的元数据信息进行Checkpoint,保存到本地,与从NameNode下载元数据进行Checkpoint的方式相比效率更高。

■ NameNode会将元数据操作的日志记录同步到Backup Node,Backup Node会将收到的日志记录在内存中更新元数据状态,同时更新磁盘上的edits,只有当两者操作成功,整个操作才成功。这样即便NameNode上的元数据发生损坏,Backup Node的磁盘上也保存了HDFS最新的元数据,从而保证了一致性。缺点

■ 高版本(0.21以上)才支持。

■ 许多特性还处于开发之中,例如:当NameNode无法工作时,Backup Node目前还无法直接接替NameNode提供服务,因此当前版本的Backup Node还不具有热备功能,也就是说,当NameNode发生故障,目前还只能通过重启NameNode的方式来恢复服务。

■ Backup Node的内存中未保存Block的位置信息,仍然需要等待下面的DataNode进行上报,因此,即便在后续的版本中实现了热备,仍然需要一定的切换时间。

■ 当前版本只允许1个Backup Node连接到NameNode。1.4.5 DRDB方案

利用DRDB机制进行元数据备份。

当NameNode发生故障时,可以启动备用机器的NameNode,读取DRDB备份的元数据信息,提供服务。优点

■ DRDB是一种较为成熟的备份机制。

■ 元数据有多个备份、并且保持最新状态。

■ 由于备份的工作交由DRDB完成,对于一条新的日志记录,NameNode无需同步写入多个备份目录,因而NameNode在效率上优于Hadoop的元数据备份方案。缺点

■ 没有做到热备、备份节点切换时间长。

■ 需要引入新的机制、由此带来一定的可靠性问题。1.4.6 FaceBook的AvatarNode方案

利用FaceBook提出的Avatar Node机制。

Active Node作为Primary NameNode对外提供服务。Standby Node处于Safe mode模式,在内存中保存Primary NameNode最新的元数据信息。Active Node和StandbyNode通过NFS共享存储进行交互。DataNode同时向Active Node和Standby Node发送Block location信息。当管理员确定Primary NameNode发生故障后,将Standby Node切换为Primary NameNode。由于Standby Node内存中保存了所有元数据的最新信息,因此可直接对外提供服务,大大缩短了切换时间。优点

■ 提供热备、切换时间大大缩短。

■ FaceBook已将其集成到自己维护的Hadoop代码中,并部署到了自己的集群使用。缺点

■ 修改了部分源码、增加了一定的复杂性,并在软件的维护性上带来一定问题。

■ 参考资料较少。

■ 只提供一个备份节点。1.5 方案优缺点比较

综上所述,HDFS HA方案比较如表1.1所示。表1.1 HDFS HA方案比较

其中“元数据备份方案”不能单独使用,因为在系统运行期间,没有相应的Checkpoint机制,会造成日志的无限制增长,因此需要和Secondary NameNode、 CheckpointNode或Backup Node配合使用。“DRDB方案”同样如此。

而对于Secondary NameNode、Checkpoint Node机制,它们只有Checkpoint的功能,而不能保存实时的元数据,因此需要在Namenode上配置元数据备份路径来保存实时元数据。

对于Backup Node,虽然它可以实时保存元数据,但为防止Backup Node成为一个单点,也需要在NameNode上配置元数据备份路径,保存在本地进行备份。总结

■ 元数据备份方案使用简单方便,在功能上可替代DRDB;

■ Backup Node是Checkpoint Node的升级版,效率更高;

■ Secondary NameNode在低版本的Hadoop中就已存在。因此用户实际上可选择的HA组合方案为:(1)元数据备份+Secondary NameNode

这种方案适用于目前Hadoop的所有版本,属于冷备,切换时间长。由于Secondary NameNode自身并不实时保存元数据,一旦NameNode上的元数据损坏,将无法恢复到最新的元数据,因此采用元数据备份机制,在NameNode上需要配置多个目录进行备份,常见的做法是再配置一个NFS节点,共享一个目录进行备份。(2)元数据备份+Backup Node

这种方案只有在0.21.0以上版本才支持,目前的实现只支持冷备,切换时间长,自身实时保存元数据,不需要NFS节点。(3)元数据备份+AvatarNode

这种方案需要打Patch(补丁包),而且只支持特定的版本(0.20)或者使用FaceBook自身的Hadoop版本,切换时间短,需要一个NFS节点作为Active节点和Standby节点的数据交互节点。

总之,如果当前Hadoop的版本较低,同时也不允许升级版本的话,可以选择第1种方案;如果版本较新(在0.21.0以上),第2种方案优于第1种;如果对HA切换时间有严格要求的话,则需要选择第3种方案。第1种方案比较简单,资料较多,本书将不再说明,后面着重讲述第2种和第3种方案。

注释【1】http://hadoop.apache.org/hdfs/【2】http://baike.baidu.com/view/849879.htm【3】http://hadoop.apache.org/common/docs/stable/hdfs_user_guide.html#Secondary+NameNode【4】https://issues.apache.org/jira/browse/HADOOP-4539【5】http://www.drbd.org/【6】https://issues.apache.org/jira/browse/HDFS-976第2章HDFS元数据解析前面已经说过,HDFS中的HA主要解决NameNode的HA,NameNode的HA最重要的目的就是维护元数据的高可用性,因此,有必要对HDFS的元数据进行深入了解。2.1 概述【1】

所谓元数据(Metadata)就是指数据的数据。HDFS的元数据就是指维护HDFS文件系统中的文件和目录所需要的信息。

需要注意的是,具体的文件内容不是元数据,元数据是用于描述和组织具体的文件内容,如果没有元数据,具体的文件内容将变得没有意义。元数据的作用十分重要,它的可用性直接决定了HDFS的可用性。

从形式上讲,元数据可分为内存元数据和元数据文件两种。其中NameNode在内存中维护整个文件系统的元数据镜像,用于HDFS的管理;元数据文件则用于持久化存储。

从类型上讲,元数据有三类重要信息:

■ 第1类是文件和目录自身的属性信息,例如文件名、目录名、父目录信息、文件大小、创建时间、修改时间等;

■ 第2类记录文件内容存储相关信息,例如文件分块情况、副本个数、每个副本所在的Data Node信息等;

■ 第3类用来记录HDFS中所有Data Node的信息,用于Data Node管理。

从来源上讲,元数据主要来源于NameNode磁盘上的元数据文件(它包括元数据镜像fsimage和元数据操作日志edits两个文件)以及各个Data Node的上报信息。

下面我们结合源码进行分析,源码的版本为0.21.0。2.2 内存元数据结构

从HDFS自身实现的角度来看,文件和目录是文件系统的基本元素,HDFS将这些元素抽象成INode,每一个文件或目录都对应一个唯一的INode,INode存储了名字信息(分别对应文件或目录的名字)同时还存储了创建时间、修改时间、父目录等信息,这些都是目录和文件的一些公共属性。

需要注意的是:有了INode信息,HDFS就可以构建整个文件系统的层次结构,并保存每个文件或目录的属性信息,用户就可以对文件和目录进行创建、删除等操作,唯一不能完成的操作是读取和写入文件的内容。2.2.1 INode

在具体实现上,类FSNamesystem的成员变量dir实现了对整个HDFS中INode的组织和操作,它是一个FSDirectory类,由于所有INode的信息完全位于内存,因此可有效提高元数据的服务性能。

正因为INode信息完全位于内存,一旦掉电将不再存在,因此需要将INode信息保存到磁盘,这个功能是由类FSImage完成的,类FSImage是构架在内存元数据与磁盘元数据文件之间的桥梁,在HDFS初始化时,它负责将磁盘元数据文件中的记录转化为内存元数据中的INode;在需要持久化存储时,它负责将元数据操作转换为日志记录并保存。

由于所有的元数据都位于内存,其大小随文件系统的规模增大而增大,如果每次都将整个内存元数据导出到磁盘,将会带来很大的系统开销,HDFS在实现时,没有采用定期导出元数据的方法,而是采用元数据镜像文件(FSImage)+日志文件(edits)的备份机制,其中镜像文件是某一时刻内存元数据的真实组织情况,而日志文件则记录了该时刻以后所有的元数据操作。

HDFS启动时会读取元数据镜像文件和日志文件到内存,进行合并形成最新的内存元数据,随后将该元数据保存到磁盘,形成新的磁盘镜像文件和日志文件;在运行过程中,HDFS不再从内存导出元数据,而只是将元数据操作记录到日志文件中。

该机制的优点是:既保证了元数据内容不丢失,同时又最大程度地降低了备份元数据的开销;缺点是:在HDFS启动加载后,进行合并会消耗一定的时间。

具体实现时,所有与元数据镜像文件有关的操作由类FSDirectory的成员变量fsImage完成,它是一个FSImage类,所有与日志文件有关的操作由类FSImage的成员变量editLog完成,它是一个FSEditLog类。2.2.2 Block

至此,我们讲到了和INode有关的几个类,通过INode我们可以知道文件的名称、创建时间、大小等属性,但这些信息对于访问某一个具体文件的内容来说是不够的。在此,我们引入HDFS中的另外一个概念——Block。

Block是对于文件内容组织而言的,我们假设一个文件的长度大小为size,那么从文件的0偏移开始,按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块就称之为一个Block,HDFS默认的Block大小为64MB,以一个256MB大小的文件为例,该文件一共有256/64=4个Block。

对于每一个Block,HDFS将其内容复制多份,以文件的形式保存到各个Data Node上,这些文件就称之为该Block的副本(Replica),HDFS中默认的副本数为3。对于1个256MB的文件来说,它有4个Block,每个Block对应有3个副本。因此,如果要访问文件指定偏移量的数据,首先可以根据Block的大小计算出该偏移所在的Block以及在该Block内的偏移,然后还要知道该Block对应的副本信息,其中最重要的信息是该副本所在的Data Node的信息。

类INodeFile中设置了一个Block的数组(protected BlockInfo blocks [] = null;)来保存该文件所有的Block信息,并提供了相应的Block操作方法。每一个Block的信息由类BlockInfo来表示,类BlockInfo中的成员变量(private Object [] triplets;)保存了该Block副本所在的Data Node的信息。每一个Data Node信息通过类DatanodeDescriptor进行描述,具体包括:容量、空间使用率、剩余容量、更新时间、主机名等。

至此,当一个客户端访问某一文件特定偏移量的内容时,HDFS首先根据路径信息找到该文件对应的INode,根据偏移计算出Block位置,在“protected BlockInfo blocks [] = null;”中找到相应的BlockInfo,然后在“private Object [] triplets;”找到副本所在Data Node的信息,然后选择其中的一个Data Node进行连接,获取相应的内容。同样,Block信息也是位于内存的,但是它不需要导出到磁盘进行存储,这是因为Block信息来源于底下各个Data Node的上报信息,这些信息由Data Node维护,因而不需要在NameNode上再进行保存。2.2.3 BlockInfo和DatanodeDescriptor

综上所述,我们可知道类INode、BlockInfo、DatanodeDescriptor是HDFS元数据的三个关键类,分别代表了三种管理对象:

■ INode代表的是文件系统基本元素:文件和目录;

■ BlockInfo代表的是文件内容对象;

■ DatanodeDescriptor代表的是具体存储对象。

前面所述的类FSDirectory实现了INode的管理,下面将对类BlockManager和NavigableMapdatanodeMap进行说明,它们分别实现了对BlockInfo和DatanodeDescriptor的管理。

类BlockManager包含了一个成员变量“final BlocksMap blocksMap;”,类BlocksMap实现了HDFS中所有Block的管理,它构建了一个Hash表“private Mapmap;”来存储所有的BlockInfo,并实现Block的快速检索及其他操作,如:以Block为输入参数,获取该Block对应的INode、设置该Block对应的INode、删除该Block对应的INode、删除该Block对应的BlockInfo、获取该Block对应的BlockInfo等。

Hash表“NavigableMapdatanodeMap”实现了HDFS中所有Data Node的管理,它存储了HDFS中所有的Data Node,通过键值StorageID可以快速定位到相应的Data Node。2.2.4 小结

至此我们从下向上对元数据的结构及相应的实现进行了说明,现在再从上到下梳理一遍:在HDFS中,由类FSNamesystem来代表总的元数据,由它对外提供统一的元数据操作接口,而这些接口的具体实现则是由它的成员变量及相关方法组合实现的,其中最重要的三个成员变量分别是:

■ public FSDirectory dir

■ BlockManager blockManager

■ NavigableMapdatanodeMap

下面我们结合具体的代码对元数据结构进行分析。2.2.5 代码分析——元数据结构

先来看类FSNamesystem的三个重要成员变量。如下所示。

类FSDirectory实现了INode的管理,并且通过成员变量“FSImage fsImage”实现了元数据信息的加载以及持久化存储。如下所示。

类FSImage是实现INode信息与元数据镜像文件fsimage以及日志文件edits之间相互转换的桥梁,其中与日志有关的功能由其成员变量“FSEditLog editLog”来实现。如下所示。

FSEdit类定义了日志操作的类型,如OP_INVALID=-1;OP_ADD=0;OP_RENAME=1;OP_DELETE=2;OP_MKDIR=3等。如下所示。

HDFS提供了一个分层的目录结构,最顶端是根目录“/”,文件系统中的每一个元素,如目录、文件等都称之为INode,每一个INode有一些公共属性和方法,如名字(protected byte [] name;),父目录(protected INodeDirectory parent;),修改时间(rotected long modificationTime;),访问时间(protected volatile long accessTime;)等。

HDFS中一共有4种类型的INode,每一种类型由一种INode子类来实现,其中:

■ 类INodeDirectory表示目录类型的INode;

■ 类INodeFile表示文件类型INode;

■ 类INodeDirectoryWithQuota是类INodeDirectory的子类,它表示有配额限制的目录;

■ 类INodeFileUnderConstruction是类INodeFile的子类,它表示正在写入的文件,当用户创建一个文件时,HDFS首先会实例化类InodeFileUnder Construction的一个对象来表示该文件,接下来用户向文件写入数据,写入结束后,HDFS会实例化一个INode对象来取代原来的类INodeFileUnderConstruction对象。

如下所示。

类BlockManager通过成员变量“final BlocksMap blocksMap;”实现HDFS所有Block的管理。

类BlocksMap通过Hash表“private Mapmap;”来存储HDFS中所有的Block,并且提供了相应的Block操作方法。

类BlockInfo是类BlocksMap的内部类,它包括“private INodeFile inode;”和“Object [] triplets;”等成员变量,其中:“private INodeFileinode;”表示该Block所对应的INode节点;*triplets[3i]代表的是第i个副本所在的Data Node,Data Node维护了一个它所存储的副本的列表,以该Block所在副本列表位置为基准,**triplets[3i+1]代表的是副本列表的前一个Block,triplets[3i+2]代表的是后一个Block。

通过Hash表“private Mapmap;”HDFS可以快速地找到当前Block的BlockInfo,然后通过BlockInfo中的**triplets[3i+1]和triplets[3i+2],HDFS可以很方便地遍历该Block所在Data Node的所有Block,通过BlockInfo中inode的“protected BlockInfo blocks[] = null;”可以很方便地遍历该Block对应文件的所有Block。如下所示。

类DatanodeDescriptor是类DatanodeInfo的子类,类DatanodeInfo的成员变量“private volatile BlockInfo blockList = null;”维护了该Data Node上所有Block的一个链表,其中:blockList是链表的头,“protected long capacity;”、“protected long dfsUsed;”、“protected long remaining;”、“protected long lastUpdate;”、“protected String hostName = null;”分别记录了Data Node节点容量、空间使用率、剩余空间、更新时间、主机名等信息。如下所示。2.3 磁盘元数据文件

NameNode启动时,所有的元数据是位于内存进行管理的,一旦掉电,内存中的数据将不复存在,为此,需要将内存中的元数据保存到磁盘永久存储。

磁盘元数据文件包括以下四个:

■ fsimage:元数据镜像文件,它存储的是某一时刻NameNode内存元数据信息,包括所有的INode信息、正在写入的文件信息以及其他的一些状态信息等;

■ edits:日志文件,它保存了该时刻以后元数据的操作记录;

■ fstime:保存了最近一次Checkpoint的时间;

■ VERSION:是一个标志性文件,它最后被创建,它的存在表明前三个元数据文件的创建成功。

下面我们通过一个简单的例子来查看下具体的元数据文件。1.解压2.配置hadoop-env.sh

在最末尾加入下面一行,配置JAVA_HOME为jdk的安装路径:3.设置环境变量

如果可以看到相应的路径,则说明设置成功。4.配置元数据备份路径

配置dfs.namenode.name.dir的value,它将作为fsimage的保存路径,可以配置多个,以“,”隔开。配置dfs.namenode.edits.dir的value,它将作为edits的保存路径,可以配置多个,以“,”隔开。本例中dfs.namenode.name.dir的value配置为/tmp/dfs/name,dfs.namenode.edits.dir的value配置为/tmp/dfs/log。如下所示。5.格式化6.检查

应该有current和image两个目录。

应该有“fsimage”、“fstime”、“VERSION”三个文件。

应该有“fsimage”一个文件。

应该有current和image两个目录。

应该有“edits”、“fstime”、“VERSION”三个文件。

应该有“fsimage”一个文件。

由上述例子我们可知:

■ fsimage和edits的保存路径可以单独设置,如果不设置edits的保存路径,那么edits默认的保存路径是fsimage的保存路径;

■ fsimage保存在fsimage保存路径的current目录下,edits保存在eidts保存路径的current目录下;

■ fsimage的保存路径以及edits的保存路径都可以设置多个,以“,”作为分隔符。

此外,fsimage文件存在两个状态,以文件名进行区分,分别是:fsimage和fsimage.ckpt。fsimage表示正常状态,fsimage.ckpt表示Checkpoint过程中,上传到NameNode的fsimage文件,Checkpoint结束时会将fsimage.ckpt重命名为fsimage。

edits也有两个状态,同样以文件名进行区分,分别是:edits和edits.new。在HDFS正常运行的过程中,元数据操作记录都会写入edits文件,当开始Checkpoint时,日志记录转而写入edits.new,而edits则作为此时刻日志的一个快照,供Checkpoint进行元数据合并,当Checkpoint结束后,会将edits.new重命名为edits。2.4 Format情景分析

和我们平时使用本地文件系统一样,HDFS在使用之前也需要格式化。所谓格式化就是对文件系统进行初始化,形成一个用户未写入数据前的初始系统。格式化操作在NameNode进行,由用户发起,具体命令调用如下。

format主要分为以下几个步骤。(1)确定能否格式化;(2)创建元数据文件在内存中的镜像;(3)对内存镜像中的数据结构进行初始化;(4)将内存镜像写入元数据备份目录。

下面结合代码对以上步骤进行分析。1.确定能否格式化

format命令的入口是类NameNode的main函数,Main函数中的主要方法是createNameNode,该方法根据输入的参数来决定执行相应的动作,对于格式化操作将调用format方法,在format方法中,遍历所有的元数据存储目录,提示用户是否允许对其格式化,如果用户不允许,则中断返回,只有用户确定允许所有目录格式化后才向下执行。2.创建元数据文件在内存中的镜像

元数据的内存镜像包括:类FSNamesystem实例化对象,类FSDirectory的实例化对象,类FSImage的实例化对象,类FSEdit的实例化对象。

■ 类FSNamesystem代表的是整个HDFS的Namespace;

■ 类FSDirectory代表了HDFS中所有的目录结构及其属性;

■ 类FSImage的实例化对象对应元数据的磁盘文件fsImage;

■ 类FSEdit的实例化对象对应元数据的磁盘文件edits。

下面我们依次进行说明。

首先是创建类FSNamesystem的对象,其构造函数主要完成3个功能:

第1是创建类BlockManager的对象;

第2是读取配置内容,对FSNamesystem的成员变量进行初始化;

第3是创建类FSDirectory对象。

类FSImage的实例化对象作为参数传入类FSNamesystem的构造函数。类FSImage的构造函数主要完成3个动作:

第1是成员变量的初始化,类FSImage是类Storage的子类,而类Storage又是类StorageInfo的子类,在类FSImage的构造函数中依次调用了父类的构造函数,最终在StorageInfo的构造函数中对layoutVersion、namespaceID、cTime这几个成员变量赋初始值0;

第2是实例化类FSEditLog的对象EditLog;

第3是对备份目录进行分类,加入到storageDirs,便于后续的目录操作。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载