Hadoop分布式文件系统(HDFS)是一个设计用于在普通硬件上运行的分布式文件系统。它与现有的分布式文件系统有许多相似之处。但是,与其他分布式文件系统的区别非常明显。HDFS是高度容错的,设计用于部署在低成本的硬件上。HDFS提供对应用程序数据的高吞吐量访问,适用于具有大数据集的应用程序。HDFS放宽了对POSIX的一些要求,允许对文件系统数据进行流访问。HDFS最初是作为Apache Nutch web搜索引擎项目的基础架构构建的。HDFS是Apache Hadoop Core项目的一部分。
硬件故障是常态,而不是例外。HDFS实例可能由数百或数千台服务器机器组成,每台机器存储文件系统数据的一部分。组件数量庞大,而且每个组件的失败概率都很高,这意味着HDFS的某些组件总是不起作用。因此,故障检测和快速、自动恢复是HDFS的核心体系结构目标。
运行在HDFS上的应用程序需要对其数据集进行流式访问。它们不是通常在通用文件系统上运行的通用应用程序。HDFS更多地被设计成批处理,而不是用户交互使用。重点是数据访问的高吞吐量,而不是低延迟的数据访问。POSIX强加了许多针对HDFS的应用程序不需要的硬需求。POSIX语义在几个关键领域已经被交换以提高数据吞吐率。
在HDFS上运行的应用程序有大量的数据集。HDFS中的一个典型文件的大小是gb到tb。因此,将HDFS调优为支持大文件。它应该提供高聚合数据带宽并可扩展到单个集群中的数百个节点。它应该在一个实例中支持数千万个文件。
HDFS应用程序需要文件的一次写,多次读访问模型。一个文件一旦创建、写入和关闭,除了附加和截断之外就不需要更改。支持将内容附加到文件末尾,但不能在任意点进行更新。这种假设简化了数据一致性问题,并支持高吞吐量数据访问。MapReduce应用程序或web爬虫应用程序非常适合这个模型。
如果应用请求的计算在其操作的数据附近执行,则其效率要高得多。当数据集很大时,尤其如此。这最小化了网络拥塞,增加了系统的总吞吐量。这里的假设是,将计算迁移到离数据更近的地方通常比将数据迁移到应用程序正在运行的地方更好。HDFS为应用提供接口,使它们更接近数据所在的位置。
HDFS被设计成易于从一个平台移植到另一个平台。这有助于将HDFS作为大量应用程序的首选平台广泛采用。
HDFS有一个主/从架构。HDFS集群由一个NameNode组成,NameNode是一个主服务器,它管理文件系统名称空间并控制客户机对文件的访问。此外,还有许多datanode,通常是集群中的每个节点一个datanode,它们管理附加到它们所运行的节点上的存储。HDFS公开文件系统名称空间,并允许将用户数据存储在文件中。在内部,一个文件被分成一个或多个块,这些块存储在一组datanode中。
NameNode执行文件系统名称空间操作,如打开、关闭和重命名文件和目录。它还确定块到datanode的映射(NameNode中存储两部分内容,每一个块的元数据约占150KB)。datanode负责处理来自文件系统客户机的读和写请求。datanode还根据来自NameNode的指令执行块创建、删除和复制。
HDFS架构图
NameNode和DataNode是为在普通机器上运行而设计的软件。这些机器通常运行GNU/Linux操作系统(OS)。HDFS是使用Java语言构建的;任何支持Java的机器都可以运行NameNode或DataNode软件。使用高度可移植的Java语言意味着HDFS可以部署在广泛的机器上。一个典型的部署有一个专用的机器,它只运行NameNode软件。集群中的其他每台机器都运行DataNode软件的一个实例。该体系结构不排除在同一台机器上运行多个datanode,但在实际部署中很少出现这种情况。
集群中单个NameNode的存在极大地简化了系统的体系结构。NameNode是所有HDFS元数据的仲裁程序和存储库。系统的设计方式是,用户数据永远不会流经NameNode。
HDFS支持传统的分层文件组织。用户或应用程序可以创建目录并将文件存储在这些目录中。文件系统名称空间层次结构与大多数其他现有文件系统相似;可以创建和删除文件,将文件从一个目录移动到另一个目录,或重命名文件。HDFS支持用户配额和访问权限。HDFS不支持硬链接或软链接。但是,HDFS体系结构并不排除实现这些特性。
虽然HDFS遵循文件系统的命名约定,但是某些路径和名称(例如:/.reservedand
.snapshot)是保留的。透明加密和快照等功能使用reserved路径。
NameNode维护文件系统名称空间。对文件系统名称空间或其属性的任何更改都由NameNode记录。应用程序可以指定HDFS应该维护的文件副本的数量。一个文件的拷贝数称为该文件的复制因子。此信息由NameNode存储。
HDFS被设计成在大型集群中的机器之间可靠地存储非常大的文件。它将每个文件存储为块序列。复制文件的块是为了容错。每个文件都可以配置块大小和复制因子。
除了最后一个块之外,文件中的所有块大小都是相同的。然而用户可以在append和hsync中添加对可变长度块的支持。可以在最后一个块长度不足固定长度时,开启一个新块。
应用可以指定文件的副本数量。复制因子可以在文件创建时指定,并且以后可以更改。HDFS中的文件只写一次(附加和截断除外),并且任何时候只能单线程写入,HDFS不支持对同一文件并发写入。
NameNode做出关于复制块的所有决定。它定期从集群中的每个datanode接收一个心跳和一个块报告。接收到心跳意味着DataNode功能正常,块报告包含DataNode上的所有块的列表。
复本的放置对HDFS的可靠性和性能至关重要。优化复制位置是HDFS与大多数其他分布式文件系统的不同之处。这是一个需要大量调优和经验的特性。支持机架的副本放置策略的目的是提高数据可靠性、可用性和网络带宽利用率。当前的复制放置策略实现是这方面的第一个尝试。实现此策略的短期目标是在生产系统上验证它,了解更多关于其行为的信息,并为测试和研究更复杂的策略打下基础。
大型HDFS实例运行在通常分布在许多机架上的计算机集群上。不同机架中的两个节点之间的通信必须经过交换机。在大多数情况下,同一机架上的计算机之间的网络带宽大于不同机架上的计算机之间的网络带宽。
NameNode通过Hadoop的机架感知过程来确定每个DataNode所属机架ID,即把副本放在不同的机架上。这可以防止在整个机架发生故障时丢失数据,并允许在读取数据时使用多个机架的带宽。这个策略在集群中均匀地分布副本,这使得在组件失败时很容易平衡负载。但是,这个策略会增加写操作的成本,因为写操作需要将块转移到多个机架。
常见情况下,当复制因子为3,HDFS复本放置策略是:
这个策略减少了机架间的写流量,从而提高了写性能。机架失效的概率远远小于节点失效的概率;此策略不影响数据可靠性和可用性保证。但是,它确实减少了读取数据时使用的聚合网络带宽,因为一个块只放在两个而不是三个唯一的机架上。使用此策略,文件的副本不会均匀地分布在机架上。三分之一的副本在一个节点上,三分之二的副本在一个机架上,另外三分之一均匀地分布在其余的机架上。该策略在不影响数据可靠性或读性能的情况下提高了写性能。
如果复制因子大于3,则随机确定第4个和后面的副本的位置,同时将每个机架的副本数量保持在上限((replicas - 1) / racks + 2)之下。
因为NameNode不允许datanode具有同一块的多个副本,所以所创建的最大副本数是当时datanode的总数。
在将对存储类型和存储策略的支持添加到HDFS之后,除了上面描述的机架感知之外,NameNode还考虑了副本放置策略。NameNode首先基于机架感知选择节点,然后检查候选节点是否具有与文件关联的策略所需的存储空间。如果候选节点不具有存储类型,则NameNode将查找另一个节点。如果在第一个路径中找不到足够的节点来放置副本,那么NameNode将在第二个路径中查找具有回退存储类型的节点。
为了最小化全局带宽消耗和读取延迟,HDFS尝试满足来自最接近读取器的副本的读取请求。如果在与读取器节点相同的机架上存在一个副本,则首选该副本来满足读取请求。如果HDFS集群跨越多个数据中心,那么驻留在本地数据中心的副本比任何远程副本更可取。
在启动时,NameNode
进入一个称为Safemode
(安全模式)的特殊状态。当NameNode
处于Safemode
状态时,不会发生数据块的复制。NameNode
接收来自datanode
的心跳和块报告消息,块报告包含DataNode
所承载的数据块列表。每个块具有指定的最小副本数。当该数据块的最小副本数量传入NameNode
,该块被认为是安全复制的。在安全复制的副本块超过集群设置最小安全数据块数量,NameNode
退出Safemode
状态。然后NameNode
确定数据块的列表(如果有的话),这些数据块仍然具有少于指定数量的副本。然后NameNode
将这些块复制到其他datanode
。
HDFS名称空间由NameNode
存储。NameNode
使用名为EditLog
的事务日志持久地记录文件系统元数据发生的每个更改。例如,在HDFS中创建一个新文件会导致NameNode
将一条记录插入到表明这一点的EditLog
中。类似地,更改文件的复制因子会导致将新记录插入EditLog
。NameNode
使用本地主机OS文件系统中的一个文件来存储EditLog
。整个文件系统名称空间(包括块到文件和文件系统属性的映射)存储在一个名为FsImage
的文件中。FsImage
也作为文件存储在NameNode
的本地文件系统中。
NameNode
在内存中保存整个文件系统名称空间和文件块映射的映像。当NameNode
启动或者一个检查点呗一个可配置的阈值触发时,它将从磁盘读取FsImage
和EditLog
,将EditLog
中的所有事务应用到FsImage
的内存表示中,并将这个新版本刷新到磁盘上的一个新FsImage
中。NameNode
不为每个编辑修改FsImage
,而是将编辑保存在Editlog
中。在检查点期间,Editlog
中的更改应用于FsImage。检查点可以在以秒为单位的给定时间间隔(dfs.namenode.checkpoint.period
)内触发,也可以在积累了给定数量的文件系统事务之后触发(dfs.namenode.checkpoint.txns
)。如果设置了这两个属性,则此进程的第一个阈值称为检查点。
检查点的目的是通过获取文件系统元数据的快照并将其保存到FsImage
,以确保HDFS具有文件系统元数据的一致视图。即使读取FsImage
是有效的,但是直接对FsImage
进行增量编辑是无效的。
DataNode
将HDFS数据存储在本地文件系统的文件中。DataNode
没有关于HDFS文件的知识。它将每个HDFS数据块存储在本地文件系统中的一个单独文件中。DataNode
不会在同一目录中创建所有文件。相反,它使用一种启发式方法来确定每个目录的最优文件数量,并适当地创建子目录。在同一个目录中创建所有本地文件并不是最佳的选择,因为本地文件系统可能无法有效地支持单个目录中的大量文件。当DataNode
启动时,它扫描本地文件系统,生成所有HDFS数据块的列表,这些数据块对应于每个本地文件,并将该报告发送给NameNode
。该报告称为Blockreport。
内容来源于网络,如有侵权,请联系作者删除!