Hadoop3.2.0 HDFS架构

Hadoop分布式文件系统(HDFS)是一种分布式文件系统,设计用于在商用硬件上运行。它与现有的分布式文件系统有许多相似之处。但是,与其他分布式文件系统的差异很大。HDFS具有高度容错能力,旨在部署在低成本硬件上。HDFS提供对应用程序数据的高吞吐量访问,适用于具有大型数据集的应用程序。HDFS放宽了一些POSIX要求,以实现对文件系统数据的流式访问。HDFS最初是作为Apache Nutch网络搜索引擎项目的基础设施而构建的。HDFS是Apache Hadoop Core项目的一部分。项目URL是http://hadoop.apache.org/

假想和目标

硬件故障

硬件故障是常态而非例外。HDFS实例可能包含数百或数千台服务器计算机,每台计算机都存储文件系统数据的一部分。事实上,存在大量组件并且每个组件具有非平凡的故障概率意味着HDFS的某些组件始终不起作用。因此,检测故障并从中快速自动恢复是HDFS的核心架构目标。

流式数据访问

在HDFS上运行的应用程序需要对其数据集进行流式访问。它们不是通常在通用文件系统上运行的通用应用程序。HDFS设计用于批处理而不是用户的交互式使用。重点是数据访问的高吞吐量而不是数据访问的低延迟。POSIX强加了许多针对HDFS的应用程序不需要的硬性要求。交易几个关键领域的POSIX语义以提高数据吞吐率

大数据集 (Large Data Sets)

在HDFS上运行的应用程序具有大型数据集。HDFS中的典型文件大小为千兆字节到太字节。因此,HDFS被调整为支持大文件。它应该为单个集群中的数百个节点提供高聚合数据带宽和扩展。它应该在单个实例中支持数千万个文件。

简单的一致性模型

HDFS应用程序需要一次只读一次读取文件的访问模型。除了追加和截断之外,无需更改创建,写入和关闭的文件。支持将内容附加到文件末尾,但无法在任意点更新。此假设简化了数据一致性问题,并实现了高吞吐量数据访问。MapReduce应用程序或Web爬网程序应用程序完全适合此模型。

“移动计算比移动数据便宜”

如果应用程序在其操作的数据附近执行,则计算所请求的计算效率更高。当数据集的大小很大时尤其如此。这可以最大限度地减少网络拥塞并提高系统的整体吞吐量。假设通常更好的是将计算迁移到更靠近数据所在的位置,而不是将数据移动到运行应用程序的位置。HDFS为应用程序提供了接口,使其自身更靠近数据所在的位置。

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

HDFS的设计便于从一个平台移植到另一个平台。这有助于广泛采用HDFS作为大量应用程序的首选平台。

NameNode和DataNodes

HDFS具有主/从架构。HDFS集群由单个NameNode,一个管理文件系统命名空间的主服务器和管理客户端对文件的访问组成。此外,还有许多DataNode,通常是群集中每个节点一个,用于管理连接到它们运行的​​节点的存储。HDFS公开文件系统命名空间,并允许用户数据存储在文件中。在内部,文件被分成一个或多个块,这些块存储在一组DataNode中。NameNode执行文件系统命名空间操作,如打开,关闭和重命名文件和目录。它还确定了块到DataNode的映射。DataNode负责提供来自文件系统客户端的读写请求。DataNodes还执行块创建,删除,

HDFS架构

NameNode和DataNode是设计用于在商用机器上运行的软件。这些机器通常运行GNU / Linux操作系统(OS)。HDFS是使用Java语言构建的; 任何支持Java的机器都可以运行NameNode或DataNode软件。使用高度可移植的Java语言意味着可以在各种计算机上部署HDFS。典型部署具有仅运行NameNode软件的专用计算机。群集中的每台其他计算机都运行一个DataNode软件实例。该体系结构不排除在同一台机器上运行多个DataNode,但在实际部署中很少出现这种情况。

群集中存在单个NameNode极大地简化了系统的体系结构。NameNode是所有HDFS元数据的仲裁者和存储库。系统的设计使用户数据永远不会流经NameNode。

文件系统命名空间

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

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

数据复制

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

除最后一个块之外的文件中的所有块都具有相同的大小,而用户可以在添加对可变长度块的支持以追加和hsync之后启动新块而不将最后一个块填充到配置的块大小。

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

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

HDFS DataNodes

副本安置:The First Baby Steps

复制品的放置对HDFS的可靠性和性能至关重要。优化副本放置可将HDFS与大多数其他分布式文件系统区分开来。这是一项需要大量调整和体验的功能。机架感知副本放置策略的目的是提高数据可靠性,可用性和网络带宽利用率。副本放置策略的当前实现是朝这个方向的第一次努力。实施此政策的短期目标是在生产系统上验证它,更多地了解其行为,并为测试和研究更复杂的策略奠定基础。

大型HDFS实例在通常分布在多个机架上的计算机群集上运行。不同机架中两个节点之间的通信必须通过交换机。在大多数情况下,同一机架中的计算机之间的网络带宽大于不同机架中的计算机之间的网络带宽。

NameNode通过Hadoop Rack Awareness中概述的过程确定每个DataNode所属的机架ID 。一个简单但非最优的策略是将复制品放在独特的机架上。这可以防止在整个机架出现故障时丢失数据,并允许在读取数据时使用来自多个机架的带宽。此策略在群集中均匀分布副本,这样可以轻松平衡组件故障的负载。但是,此策略会增加写入成本,因为写入需要将块传输到多个机架。

对于常见情况,当复制因子为3时,HDFS的放置策略是在编写器位于datanode上时将一个副本放在本地计算机上,否则放在与写入器相同的机架中的随机datanode上,另一个副本位于不同(远程)机架中的节点,以及同一远程机架中不同节点上的最后一个节点。此策略可以减少机架间写入流量,从而提高写入性能。机架故障的可能性远小于节点故障的可能性; 此策略不会影响数据可靠性和可用性保证。但是,它确实减少了读取数据时使用的聚合网络带宽,因为块只放在两个唯一的机架而不是三个。使用此策略时,文件的副本不会均匀分布在机架上。三分之一的副本位于一个节点上,三分之二的副本位于一个机架上,另外三个副本均匀分布在剩余的机架上。此策略可提高写入性能,而不会影响数据可靠性或读取性能。

如果复制因子大于3,则随机确定第4个及以下副本的放置,同时保持每个机架的副本数量低于上限(基本上是(副本 - 1)/机架+ 2)。

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

在将存储类型和存储策略的支持添加到HDFS之后,除了上述机架感知之外,NameNode还会考虑策略以进行副本放置。NameNode首先根据机架感知选择节点,然后检查候选节点是否具有与文件关联的策略所需的存储。如果候选节点没有存储类型,则NameNode将查找另一个节点。如果在第一个路径中找不到足够的节点来放置副本,则NameNode会在第二个路径中查找具有回退存储类型的节点。

此处描述的当前默认副本放置策略是正在进行的工作。

副本选择

为了最大限度地减少全局带宽消耗和读取延迟,HDFS尝试满足最接近读取器的副本的读取请求。如果在与读取器节点相同的机架上存在副本,则该副本首选满足读取请求。如果HDFS群集跨越多个数据中心,则驻留在本地数据中心的副本优先于任何远程副本。

安全模式

在启动时,NameNode进入一个名为Safemode的特殊状态。当NameNode处于Safemode状态时,不会发生数据块的复制。NameNode从DataNode接收Heartbeat和Blockreport消息。Blockreport包含DataNode托管的数据块列表。每个块都有指定的最小副本数。当使用NameNode检入该数据块的最小副本数时,会认为该块是安全复制的。在可配置百分比的安全复制数据块使用NameNode检入(再加上30秒)后,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进行增量编辑效率不高。我们不会为每次编辑修改FsImage,而是在Editlog中保留编辑内容。在检查点期间,Editlog的更改将应用​​于FsImage。可以在给定的时间间隔触发检查点(dfs.namenode.checkpoint.period)以秒为单位表示,或者在累积了给定数量的文件系统事务之后(dfs.namenode.checkpoint.txns)。如果同时设置了这两个属性,则要达到的第一个阈值将触发检查点。

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

通信协议

所有HDFS通信协议都在TCP / IP协议之上。客户端建立与NameNode计算机上可配置TCP端口的连接。它将ClientProtocol与NameNode进行对话。DataNode使用DataNode协议与NameNode通信。远程过程调用(RPC)抽象包装客户端协议和DataNode协议。按照设计,NameNode永远不会启动任何RPC。相反,它只响应DataNodes或客户端发出的RPC请求。

稳健性

HDFS的主要目标是即使在出现故障时也能可靠地存储数据。三种常见的故障类型是NameNode故障,DataNode故障和网络分区。

数据磁盘故障,心跳和重新复制

每个DataNode定期向NameNode发送Heartbeat消息。网络分区可能导致DataNode的子集失去与NameNode的连接。NameNode通过缺少Heartbeat消息来检测此情况。NameNode将没有最近Heartbeats的DataNodes标记为已死,并且不会将任何新的IO请求转发给它们。注册到死DataNode的任何数据都不再可用于HDFS。DataNode死亡可能导致某些块的复制因子低于其指定值。NameNode不断跟踪需要复制的块,并在必要时启动复制。由于许多原因可能会出现重新复制的必要性:DataNode可能变得不可用,副本可能已损坏,DataNode上的硬盘可能会失败,

标记DataNodes死机的超时是保守的,使用较长时间(默认情况下超过10分钟),以避免由DataNode状态抖动引起的复制风暴。用户可以设置较短的间隔以将DataNode标记为陈旧,并通过配置为性能敏感的工作负载避免过时的节点读取和/或写入。

群集重新平衡

HDFS架构与数据重新平衡方案兼容。如果DataNode上的可用空间低于某个阈值,则方案可能会自动将数据从一个DataNode移动到另一个DataNode。如果对特定文件的需求突然高,则方案可以动态创建其他副本并重新平衡群集中的其他数据。这些类型的数据重新平衡方案尚未实施。

数据的完整性

从DataNode获取的数据块可能已损坏。由于存储设备中的故障,网络故障或有缺陷的软件,可能会发生此损坏。HDFS客户端软件对HDFS文件的内容进行校验和检查。当客户端创建HDFS文件时,它会计算文件每个块的校验和,并将这些校验和存储在同一HDFS命名空间中的单独隐藏文件中。当客户端检索文件内容时,它会验证从每个DataNode接收的数据是否与存储在关联校验和文件中的校验和匹配。如果没有,则客户端可以选择从具有该块的副本的另一个DataNode中检索该块。

元数据磁盘故障

FsImage和EditLog是HDFS的中心数据结构。这些文件损坏可能导致HDFS实例无法正常运行。因此,NameNode可以配置为支持维护FsImage和EditLog的多个副本。对FsImage或EditLog的任何更新都会导致每个FsImages和EditLogs同步更新。这种FsImage和EditLog的多个副本的同步更新可能会降低NameNode可以支持的每秒命名空间事务的速率。但是,这种降级是可以接受的,因为即使HDFS应用程序本质上是数据密集型的,它们也不是元数据密集型的。当NameNode重新启动时,它会选择要使用的最新一致FsImage和EditLog。

增加故障恢复能力的另一个选择是使用多个NameNode 在NFS上使用共享存储或使用分布式编辑日志(称为Journal)来启用高可用性。后者是推荐的方法。

快照

快照支持在特定时刻存储数据副本。快照功能的一种用途可以是将损坏的HDFS实例回滚到先前已知的良好时间点。

数据组织

数据块

HDFS旨在支持非常大的文件。与HDFS兼容的应用程序是处理大型数据集的应用程序。这些应用程序只写入一次数据,但是它们读取一次或多次,并要求在流速下满足这些读取。HDFS支持文件的一次写入多次读取语义。HDFS使用的典型块大小为128 MB。因此,HDFS文件被切碎为128 MB块,如果可能,每个块将驻留在不同的DataNode上。

复制流水线

当客户端将数据写入复制因子为3的HDFS文件时,NameNode使用复制目标选择算法检索DataNode列表。此列表包含将承载该块副本的DataNode。然后客户端写入第一个DataNode。第一个DataNode开始分批接收数据,将每个部分写入其本地存储库,并将该部分传输到列表中的第二个DataNode。第二个DataNode又开始接收数据块的每个部分,将该部分写入其存储库,然后将该部分刷新到第三个DataNode。最后,第三个DataNode将数据写入其本地存储库。因此,DataNode可以从流水线中的前一个接收数据,同时将数据转发到流水线中的下一个。从而,

无障碍

可以通过多种不同方式从应用程序访问HDFS。本地,HDFS 为应用程序提供了FileSystem Java API。一本Java API的C语言包装REST API也是可用的。此外,还有HTTP浏览器,也可用于浏览HDFS实例的文件。通过使用NFS网关,HDFS可以作为客户端本地文件系统的一部分进行安装。

FS Shell

HDFS允许以文件和目录的形式组织用户数据。它提供了一个名为FS shell的命令行界面,允许用户与HDFS中的数据进行交互。此命令集的语法类似于用户已熟悉的其他shell(例如bash,csh)。以下是一些示例操作/命令对:

行动 命令
创建一个名为/ foodir的目录 bin/hadoop dfs -mkdir /foodir
删除名为/ foodir的目录 bin/hadoop fs -rm -R /foodir
查看名为/foodir/myfile.txt的文件的内容 bin/hadoop dfs -cat /foodir/myfile.txt

FS shell适用于需要脚本语言与存储数据交互的应用程序。

DFSAdmin

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

行动 命令
将群集进入 Safemode 中 bin/hdfs dfsadmin -safemode enter
生成DataNode列表 bin/hdfs dfsadmin -report
重新发布或退役DataNode(s) bin/hdfs dfsadmin -refreshNodes

浏览器界面

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

空间回收

文件删除和取消删除

如果启用了垃圾箱配置,则FS Shell删除的文件不会立即从HDFS中删除。相反,HDFS将其移动到垃圾目录(每个用户在/user/<username>/.Trash下都有自己的垃圾目录)。只要文件保留在垃圾箱中,就可以快速恢复该文件。

最近删除的文件被移动到当前的垃圾箱目录(/user/<username>/.Trash/Current),并且在可配置的时间间隔内,HDFS创建了检查点(在/user/<username>/.Trash/<date>下)对于当前废纸篓目录中的文件,并在过期时删除旧检查点。有关垃圾箱的检查点,请参阅FS shell的expunge命令

在其生命周期到期后,NameNode将从HDFS命名空间中删除该文件。删除文件会导致释放与文件关联的块。请注意,在用户删除文件的时间与HDFS中相应增加的可用空间之间可能存在明显的时间延迟。

以下是一个示例,它将显示FS Shell如何从HDFS中删除文件。我们在目录delete下创建了2个文件(test1和test2)

$ hadoop fs -mkdir -p delete/test1
$ hadoop fs -mkdir -p delete/test2
$ hadoop fs -ls delete/
Found 2 items
drwxr-xr-x   - hadoop hadoop          0 2015-05-08 12:39 delete/test1
drwxr-xr-x   - hadoop hadoop          0 2015-05-08 12:40 delete/test2

我们将删除文件test1。下面的注释显示该文件已移至“废纸篓”目录。

$ hadoop fs -rm -r delete/test1
Moved: hdfs://localhost:8020/user/hadoop/delete/test1 to trash at: hdfs://localhost:8020/user/hadoop/.Trash/Current

现在我们将使用skipTrash选项删除该文件,该选项不会将文件发送到Trash。它将从HDFS中完全删除。

$ hadoop fs -rm -r -skipTrash delete/test2
Deleted delete/test2

我们现在可以看到Trash目录只包含文件test1。

$ hadoop fs -ls .Trash/Current/user/hadoop/delete/
Found 1 items\
drwxr-xr-x   - hadoop hadoop          0 2015-05-08 12:39 .Trash/Current/user/hadoop/delete/test1

因此文件test1进入垃圾箱并永久删除文件test2。

减少复制因子

当文件的复制因子减少时,NameNode选择可以删除的多余副本。下一个Heartbeat将此信息传输到DataNode。然后,DataNode将删除相应的块,并在群集中显示相应的可用空间。再一次,setReplication API调用完成与集群中可用空间的出现之间可能存在时间延迟。

参考

Hadoop JavaDoc API

HDFS源代码:http://hadoop.apache.org/version_control.html

猜你喜欢

转载自blog.csdn.net/weixin_42868638/article/details/89342093