赞
踩
在“分布式系列之分开源分布式存储技术分析”中提到HDFS是以中间控制节点为代表的分布式存储架构,一部分节点 NameNode 是存放管理数据,另一部分节点DataNode存放业务数据。本文简要整理HDFS分布式文件系统的整体架构和关键技术,进一步了解不同分布式存储技术实现原因上的差异。
HDFS是Hadoop核心项目的子项目,是分布式计算中数据存储管理的基础,具有高容错性、可扩展性,适合大数据量处理和流式批处理,可运行于廉价的服务器上。传统的HDFS架构采用master/slave架构,一个HDFS集群是由一个Namenode和一定数目的Datanodes组成。
总之,HDFS暴露了文件系统的名字空间NameSpace,用户能够以文件的形式在上面存储数据。从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组Datanode上。Namenode执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录,同时也负责确定数据块到具体Datanode节点的映射。Datanode负责处理文件系统客户端的读写请求。在Namenode的统一调度下进行数据块的创建、删除和复制。
HDFS中的数据块Block是逻辑概念,默认块为64MB,block是HDFS分布式文件系统中的文件存储的逻辑单元。通常一个文件系统块为几千字节,磁盘块为512字节,HDFS的块比磁盘块大,其目的是为了最小化寻址开销。如果块设置得足够大,从磁盘传输数据的时间可以明显大于定位这个块开始位置所需的时间。这样,传输一个由多个块组成的文件的时间取决于磁盘传输速率。HDFS中使用逻辑的block有以下好处:
在HDFS集群中,元数据放在内存中,在磁盘中备份元数据的FsImage,防止因为断电,造成元数据丢失。当在内存中的元数据更新时,同时更新FsImage的效率非常低,所以HDFS引入Edits文件。每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中。这样,一旦NameNode节点断电,可以通过FsImage和Edits的合并,恢复元数据。为了避免长时间添加数据到Edits中,导致文件数据过大,效率降低的问题,HDFS会定期进行FsImage和Edits的合并,合并操作由NameNode完成。但是由于NameNode还有其他的任务,比如协调DataNode工作等,这会使NameNode的压力倍增,所以HDFS引入了Secondary Namenode这一角色,专门负责FsImage和Edits的合并。
1)第一阶段:NameNode启动
2)第二阶段:Secondary NameNode工作
一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度、块数据的校验和以及时间戳。
HDFS支持传统的层次型文件组织结构。用户或者应用程序可以创建目录,然后将文件保存在这些目录里。Namenode 负责维护文件系统的名字空间,任何对文件系统名字空间或属性的修改都将被Namenode 记录下来。HDFS 会给客户端提供一个统一的目录树,客户端通过路径来访问文件,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data。
HDFS的文件写入原理,主要包括以下几个步骤:
HDFS的文件读取原理,主要包括以下几个步骤:
在Hadoop2.X之前,Namenode在HDFS集群中是单点的,每个HDFS集群只有一个namenode,一旦这个节点不可用,则整个HDFS集群将处于不可用状态。HDFS高可用(HA)方案就是为了解决上述问题而产生的,在HA HDFS集群中会同时运行两个Namenode,一个作为Active Namenode(Active),一个作为Standby Namenode。Standby Namenode的命名空间与Active Namenode是实时同步的,所以当Active Namenode发生故障而停止服务时,Standby Namenode可以立即切换为活动状态,从而不影响HDFS集群服务。
为了使Standby节点与Active节点的状态能够同步一致,两个节点都需要同一组独立运行的节点(JournalNodes,JNS)通信。当Active Namenode执行了修改命名空间的操作时,它会定期将执行的操作记录在editlog中,并写入JNS的多数节点中。而Standby Namenode会一直监听JNS上editlog的变化,如果发现editlog有改动,Standby Namenode就会读取editlog并与当前的命名空间合并。当发生了故障切换时,Standby节点会保证已经从JNS上读取了所有editlog并与命名空间合并,然后才会从Standby状态切换为Active状态。通过这种机制,保证了Active Namenode与Standby Namenode之间命名空间状态的一致性。
为了使故障切换能够很快的执行完毕,就要保证Standby节点也保存了实时的数据块的存储信息。这样在发生故障切换时,Standby节点就不需要等待所有的数据节点进行全量数据块同步,而直接可以切换到Active状态。为了实现这个机制,Datanode会同时向这两个Namenode发送心跳以及块状态信息。这样就实现了Active Namenode 和standby Namenode 的元数据就完全一致,一旦发生故障,就可以马上切换,也就是热备。
这里需要注意的是 Standby Namenode只会更新数据块的存储信息,并不会向namenode 发送复制或者删除数据块的指令,这些指令只能由Active namenode发送。
如果Zookeeper客户端机器负载过高或者正在进行JVM Full GC,那么可能会导致Zookeeper客户端到服务端的心跳不能正常发出,一旦这个时间持续较长,超过了配置的Zookeeper Session Timeout参数的话, Zookeeper服务端就会认为客户端的session已经过期从而将客户端的Session关闭。“假死”有可能引起分布式系统常说的双主或脑裂(brain-split)现象。在HA架构中需要保证同一时刻只有一个处于Active状态的Namenode,否则就会出现两个Namenode同时修改命名空间的问题,也就是脑裂(Split-brain)。脑裂的HDFS集群很可能造成数据块的丢失,以及向Datanode下发错误的指令等异常情况。为了预防脑裂的情况,HDFS提供了三个级别的隔离机制(fencing):
HDFS的HA高可用架构中,Active NameNode和Standby NameNode之间需要共享editlog日志文件。Active Namenode会将日志文件写到共享存储上,Standby Namenode会实时的从共享存储读取edetlog文件,然后合并到Standby Namenode的命名空间中。这样一旦Active Namenode发生错误,Standby Namenode可以立即切换到Active状态。在Hadoop2.6中,提供了QJM(Quorum Journal Manager)方案来解决HA共享存储问题,Quorum Journa是一个基于paxos算法的HA设计方案。基于 QJM 的共享存储系统主要用于保存EditLog,并不保存 FSImage 文件。 FSImage 文件还是在 NameNode 的本地磁盘上。
Quorum Journal方案依赖于这样一个概念:HDFS集群中有2N+1个JN存储editlog文件,这些editlog文件是保存在JN的本地磁盘上的。每个JN对QJM暴露QJM接口QJournalProtocol,允许Namenode读写editlog文件。当Namenode向共享存储写入editlog文件时,它会通过QLM向集群中所有的JN发送写editlog文件请求,当有一半以上的JN返回写操作成功时,即认为写成功。
本文主要介绍了HDFS的整体架构,NameNode和DataNode的工作原理,以及HDFS的读写流程,最后介绍HDFS架构演进下高可用的实现机制。
参考资料:
转载请注明原文地址:https://blog.csdn.net/solihawk/article/details/123981573
文章会同步在公众号“牧羊人的方向”更新,感兴趣的可以关注公众号,谢谢!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。