HDFS架构及原理理解

概述

HDFS全称是Hadoop Distributed File System,也就是Hadoop分布式文件系统,是Apache Hadoop的核心工程。HDFS具有高度容错能力,旨在部署在低成本硬件上。HDFS提供对应用程序数据的高吞吐量访问,适用于具有大型数据集的应用程序。

这里讨论一下我对HDFS架构及原理的理解。

NameNode,DataNodes和客户端

HDFS有一个master/slave架构。一个HDFS集群由一个单一的NameNode和大量的DataNode组成。

NameNode是一个master服务,是所有HDFS元数据的仲裁者和存储库,负责管理文件系统命名空间(namespace)和控制客户端对文件的访问。系统的设计使用户数据永远不会流经NameNode。

DataNode通常是集群中的每个节点上有一个,用于管理连接到它们运行的节点的存储,HDFS的架构没有排除在同一台机器上运行多个DataNode的可能性,但是在真正的部署中很少见。

HDFS公开文件系统命名空间,并允许用户数据存储在文件中。在内部,一个文件被分成一个或多个块,这些块存储在一组DataNode中。

NameNode执行文件系统命名空间操作,如打开,关闭和重命名文件和目录。它还确定了块到DataNode的映射,也就是块存储的元数据。DataNode负责处理来自文件系统客户端的读写请求。DataNodes也执行块创建,删除,和根据NameNode指令进行块复制。

NameNode作出有关块复制的所有决定。它定期从集群中的每个DataNode接收Heartbeat和Blockreport。收到心跳意味着DataNode正常运行。一个Blockreport包含一个DataNode上所有块的列表。

HDFS客户端对HDFS文件的内容进行校验和检查。当客户端创建HDFS文件时,它会计算文件每个块的校验和,并将这些校验和存储在同一HDFS命名空间中的单独隐藏文件中。当客户端检索文件内容时,它会验证从每个DataNode接收的数据是否与存储在关联校验和文件中的校验和匹配。如果没有,则客户端可以选择从具有该块的副本的另一个DataNode中检索该块。

写操作流程

  1. 客户端向NameNode请求上传文件,NameNode会对上传目录和文件进行检查,判断是否可以上传,然后将检查结果反馈给客户端。
  2. 客户端在得到可以上传的允许后,会读取本地配置,然后开始在本地缓存文件数据,当缓存到一个数据块大小时,就向NameNode请求上传一个数据块,这时NameNode会根据客户端配置检查DataNode信息,然后返回一个DataNode列表给客户端。
  3. 客户端获取到DataNode列表后,会和第一个DataNode建立连接,然后开始进行流式的传输,第一个DataNode分批的接收数据,保存到本地仓库,同时将这些数据传输给第二个DataNode,第二个DataNode也将数据保存到本地仓库,同时将数据发传输给第三个DataNode,依次类推。
  4. 当数据块传输完成,第一个DataNode会反馈给客户端,客户端再反馈给NameNode,然后NameNode会更新元数据信息。
  5. 文件其他的数据块按照同样的方法传输,直到整个文件上传完成。

文件系统命名空间

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

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

数据复制

HDFS旨在可靠地在大型集群中跨机器存储非常大的文件。它将每个文件存储为一系列块。复制文件的块以实现容错。块大小和副本因子可根据文件配置。

除了最后一个块,一个文件的所有块都是相同大小的。用户也可以添加可变长度块的支持。

应用程序可以指定一个文件的副本数。副本因子可以在文件创建时指定,并可以在以后更改。HDFS中的文件是一次写入的(除了追加和截断),并且严格意义上,在任何时候只有一个写入器。

副本放置策略

副本的放置对HDFS的可靠性和性能至关重要。机架感知副本放置策略的目的是提供数据可靠性,可用性和网络带宽利用率。

NameNode通过机架感知确定每个DataNode所属的机架ID。

对应常见情况,当复制因子为3时,HDFS的放置策略是在写入器位于DataNode上时将第一个副本放在本地计算机上,否则放在与写入器相同的机架中的随机DataNode上,另一个副本放在不同(远程)机架的节点上,最后一个副本放在同一远程机架的一个不同节点上。

此策略可以减少机架间写入流量,从而提供写入性能。机架故障的可能性远小于节点故障的可能性,此策略不会影响数据数据可靠性和可用性保证。但是,它确实减少了读取数据时使用的聚合网络带宽,因为块只放在两个唯一的机架而不是三个。

由于NameNode不允许DataNode具有同一块的多个副本,因此创建的最大副本数是此时DataNode的总数。

机架感知

Hadoop主守护进程通过调用配置文件指定的外部脚本或Java类来获取集群工作者的机架ID。使用Java类或外部脚本进行拓扑。

使用外部脚本时,除了提供脚本,还需要脚本可识别的相应的节点的IP,主机名和机架ID的信息文件。

更多信息可参考 Hadoop Rack Awareness。

复制流水线pipeline

当Client将数据写入复制因子为3的HDFS文件时,NameNode使用复制目标选择算法检索DataNode列表。此列表包含将承载该块副本的DataNode。然后Client写入第一个DataNode。第一个DataNode开始分批接收数据(一批就是一个数据包,默认64K),将每批数据写入其本地存储库,接收完一批数据就开始讲其传输到列表中的第二个DataNode。第二个DataNode又开始分批接收数据块,同理传输到列表中的第三个DataNode。

假设流水线有A,B,C三个DataNode。A每传一个包,就会放入应答队列等待应答,等B的应答,B又等待C的应答,当数据全部传输完成,并且A收到正确的应答,那么A就会将结果发送给Client。

当一个数据块传输完成后,Client再次请求NameNode上传第二个数据块。

副本读取策略

为了最大限度的减少全局带宽消耗和读取延迟,HDFS尝试满足最接近读取器的副本的读取请求。

如果在与读取器相同的机架上存在副本,则该副本首先满足读取需求。如果HDFS集群跨越多个数据中心,则驻留在本地数据中心的副本优先于任何远程副本。

安全模式

在启动时,NameNode进入一个名为Safemode的特殊模式。当NameNode处于Safemode状态时,不会发生数据块的复制。这时,NameNode从DataNode接收Heartbeat和Blockreport信息。Blockreport包含DataNode托管的数据块列表。每个块都有指定的最小副本数。当NameNode检入该数据块的最小副本数时,会认为该块是安全复制的。在可配置百分比的安全复制数据块使用NameNode检入(在加上30s)后,NameNode退出Safemode状态。然后,它确定仍然具有少于指定副本数的数据块列表(如果有)。然后NameNode将这些块复制到其他DataNode。

文件系统元数据的持久性

HDFS命名空间由NameNode存储。NameNode使用名为EditLog的事务日志来持久记录文件系统元数据发生的每个更改。例如,在HDFS中创建新文件会导致NameNode将记录插入EditLog,以指示此情况。同样,更改文件的复制因子会导致将新纪录插入EditLog。NameNode使用其本地主机OS文件系统中的文件来存储EditLog。整个文件系统命名空间(包括块到文件和文件系统属性的映射)存储在名为FsImage的文件中。FsImage也作为文件存储在NameNode的本地文件系统中。

NameNode在内存中保存整个文件系统的命名空间和文件Blockmap的镜像。当NameNode启动,或者检查点由可配置的阈值触发时,它从磁盘读取FsImage和EditLog,将EditLog中的所有事务应用到FsImage的内存镜像,并将此新版本刷新为磁盘上的新FsImage。然后它可以截断旧的EditLog,因为它的事务以应用于持久的FsImage。此过程称为检查点。检查点的目的是通过获取文件系统元数据的快照并将其保存到FsImage来确保HDFS具有文件系统元数据的一致视图。尽管读取FsImage是有效的,但直接对FsImage进行增量编辑效率不高。对文件系统的每次编辑会先保存到EditLog中,然后NameNode会在启动或者检查点触发时,将EditLog应用到FsImage中。检查点的触发条件有两个,一个是配置的时间间隔,另一个是累积的事务数量达到配置值,只要满足一个条件就可以出发检查点。

DataNode将HDFS数据存储在其本地文件系统中的文件中。DataNode不了解HDFS文件。它将每个HDFS数据块存储在其本地文件系统的单独文件中。DataNode不会在同一目录中创建所有文件。相反,它使用启发式方法来确定每个目录的最佳文件数,并适当的创建子目录。在同一目录创建所有本地文件并不是最佳选择,因为本地文件系统可能无法有效地支持单个目录的大量文件。当DataNode启动时,它会扫描其本地文件系统,生成与每个本地文件对应的所有的HDFS数据块的列表,并将此报告发送到NameNode。该报告称为Blockreport。

HA和QJM

为了解决NameNode的单点故障,HDFS在2.0.0版本增加了High Availability (HA)特性,在同一个集群中提供两个具有热备作用的NameNode(在3.0.0版本中,可多于两个),在运行时,一主一备。两个NameNode之间的数据共享可以通过Quorum Journal Manager(QJM)实现。

在典型的HA集群中,两个或多个单独的计算机配置为NameNode。在任何时间点,其中一个NameNode处于活动状态(Active),而其他的NameNode处于备用状态(Standby)。活动NameNode负责集群中的所有客户端操作,备用NameNode只是充当工作者,维持足够的状态,以便在必要时提供快速故障转移。

为了使备用节点与活动节点保持状态同步,两个节点都与一组称为“JournalNodes”(JN)的单独守护进程通信。当活动节点执行任何命名空间修改时,它会将修改记录持久的记录到大多数这些JN中。备用节点能够从JN读取编辑,并且不断观察它们对编辑日志的修改。当备用节点看到编辑时,它会将它们应用到自己的命名空间。如果发生故障转移,备用节点将确保在将自身提升为活动节点之前已从JN读取所有编辑内容。这可确保在发生故障转移之前完全同步命名空间状态。

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

对应HA集群的正确操作而言,一次只有一个NameNode处于活动状态至关重要。否则,命名空间将在NameNode之间快速分歧,造成数据丢失或者其他不正确的结果。为了确保这个属性并防止“脑裂”,JN将一次只允许一个NameNode进行写入操作。在故障转移期间,要激活的NameNode将简单地接管写入JN的角色,这将有效地阻止其他NameNode继续处于活动状态,从而允许新的活跃节点安全地进行故障转移。

你可能感兴趣的:(Bigdata,hadoop,hdfs)