3.1 HDFS Architecture (HDFS)

介绍

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

假设和目标

硬件故障

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

流数据访问

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

大数据集

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

简单的一致性模型

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

移动计算比移动数据廉价

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

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

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

NameNode和DataNodes

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

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。收到Heartbeat意味着DataNode正常运行。Blockreport包含DataNode上所有块的列表。

副本放置:第一个步骤

副本的放置对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将最近没有心跳的Datanode标记为Dead状态,并且不会将任何新的IO请求转发给它们。注册到Dead DataNode的任何数据都不再可用于HDFS。DataNode死亡可能导致某些块的复制因子低于其指定值。NameNode不断跟踪需要复制的块,并在必要时启动复制。由于许多原因可能会出现重新复制的必要性:DataNode可能变得不可用,副本可能会损坏,DataNode上的硬盘可能会失败,

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

群集重新平衡

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

posted @ 2018-10-26 13:25  走过冬季  阅读(224)  评论(0编辑  收藏  举报