HDFS 架构指南 2.6.0 译

HDFS 架构指南 2.6.0

本文是对下面链接中文字的翻译

http://hadoop.apache.org/docs/r2.6.0/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html

简介

HDFS 是一个可以运行在普通硬件上的分布式文件系统。跟现有的分布式系统相比,它有不少相似性。然而,区别也是很大的。 HDFS是高度容错性,设计的初衷就是可在低成本的硬件上部署。HDFS提供高吞吐量的访问,适用于拥有大容量数据集的应用。 HDFS突破了一些POSIX需求,允许了对文件系统数据的流式访问。HDFS的初衷是为Apache Nutch 网络搜索引擎项目作为基础。目前HDFS是一个Apache Hadoop 的子项目。项目链接是http://hadoop.apache.org/hdfs/.

假设和目标

硬件故障

硬件故障是常态,而不是例外。 一个HDFS实例可能包含成千上万的服务器,每个服务器都保存着文件系统的部分数据。如此众多的组件以及每个组件都有可能发生故障,这个实际情况疑为这HDFS的一些组件总是不会正常工作的。因此,故障检测和快速,自动的恢复是HDFS核心的架构目标。

数据流式访问

运行在HDFS上的应用需要流式访问数据。没有通过目标的应用运行在通用的文件系统上。 HDFS设计上,侧重于批处理,而不是用户的交互式操作。 强调的重点是大量数据访问的高吞吐速率,而不是数据访问的低延时。POSIX很多硬性的要求并不适用于运行在HDFS上的应用。 POSIX标准在一些关键领域已经做了修改,以提高数据吞吐速率。

大数据集

运行在HDFS上的应用处理大数据集。 典型的HDFS上的文件大小从几个G到几个T。因此,HDFS为支持大文件做了优化。一方面要再一个集群中提供比较大的总的数据带宽,并能扩展到基本个节点,另一方面面一个实例应该能支持上千万个文件。

简单的聚合模型

HDFS应用对文件的访问模式是写一次,读多次。一旦一个文件创建,关闭,文件就不会在改变了。这个假定简化了数据聚合问题,方便了数据的高吞吐量访问。一个MapReduce应用或者一个网络爬虫应用就非常适合这种模式。当然,将来会支持后续附加的文件写模式,已经有一个开发计划。

“移动计算比移动数据要合算”

应用发起的计算在靠近数据的地方运行更加有效率,尤其是数据量巨大的时候,因为这样减少了网络拥塞,提高了系统总的吞吐效率。移动计算到数据,而不是移动数据到计算运行的地方。应用可以借助HDFS提供的接口,把自己移动到数据所在的地方。

跨多种硬件和软件平台的可移植性

HDFS的设计允许跨平台的移植性。这个设计促进大量的应用选择HDFS。

NameNode和DataNodes

HDFS 是一个主从架构。一个HDFS集群包含单个NameNode。 NameNode是一个主服务器,管理文件系统的名字空间,控制着客户端对于文件的访问。HDFS包含多个DataNodes,通常是一个集群中每个节点有一个DataNode。DataNode管理着数据。HDFS对外呈现的是一个文件系统的名字空间,用户的数据存放于文件之中。HDFS内部则是把一个文件分成一个或者多个文件块,存储于一组DataNodes中。NameNode负责执行文件系统的操作,比如打开文件,关闭文件,重命名文件或者目录,也决定了内部的文件块和DataNode的映射。DataNodes负责提供文件系统客户端的数据读写请求,和执行文件块的创建,删除,复制(响应NameNode指令)

 NameNode和DataNode可以运行在普通机器上的软件。这些机器通常是运行GNU/Linux操作系统。HDFS用Java 语言编写。任何支持Java的机器都可以运行NameNode和DataNode。用Java这种感觉可移植性性的语言意味着HDFS可以部署在各种类型的机器上。一个典型的部署有一个单独的机器只运行NameNode,而其他集群中的机器每个运行一个DataNode。HDFS的架构并没有限制一台机器上可以运行多个DataNodes,但是,很少有这样部署的。

一个集群中只有一个NameNode极大地简化了系统的架构。NameNode控制和管理着所有的HDFS元数据。用户数据永远也不会存储到NameNode上。

文件系统的命名空间

HDFS支持传统的文件系统的层级架构。一个用户或者应用程序可以创建目录,进而在目录中存储文件。文件系统给的名字空间层级架构跟现有的文件系统非常类似。文件可以长久,删除,从一个目录移动到另一个目录,或者重命名。HDFS目前还没有实现用户的配额机制。HDFS不支持软硬链接,尽管架构上并没有限制这些功能的实现。

NameNode维护着一个文件系统的名字空间。对文件系统名字空间或者属性的任何改变都记录在NameNode中。应用能指定一个文件可以有多少个副本。一个文件副本的数目成为文件的复制因子,存储在NameNode中。

数据复制

在大的集群中,HDFS可以跨机器可靠地存储非常大的文件。每个文件被存储为一系列的块。除了最后以个块,其他所有的文件块大小都一样。为了容错,文件块会被复制。每个文件的块的大小和复制因子都可以单独配置。一个应用可以指定一个文件的副本的数目,复制因子既可以在文件创建的时候指定,也可以文件创建以后修改。HDFS中的文件只能写一次,任何时候只能有一个写的实例。

NameNode负责所有关于块的复制 决定。它周期性地从集群中每个DataNode接收心跳信号和块汇报。心跳信号标记着DataNode工作正常,块汇报包含了DataNode上所有的文件块。

副本放置: 首孩步骤

副本的放置对于HDFS的可靠性和性能至关重要。副本放置的优化是HDFS区别于其他分布式文件系统的重要标志。这个特性需要大量的调试和经验。机架感知的副本放置策略的目的是提高数据的可靠性,可用性,并能节省网络带宽的使用。目前的实现策略是朝着这个目标迈出的第一步。短期目的是在生产系统上验证,更多的了解其行为,为测试和研究更加复杂的策略打好基础。

大型HDFS应用实例运行在一个跨多个机架的计算机集群上。不同机架上的两个节点的数据交互需要通过交换机。大多数情况下,同一个机架上的两个节点之间的网络带宽高于不同机架上的带宽。

NameNode 根据Hadoop Rack Awareness 流程确定了每个DataNode的机架Id。 一个简单可是不太优化的策略是把副本放在不同的机架上。在一个机架出故障的时候,数据不会丢失,而且,读取数据的时候,可以充分利用多个机架的带宽。这个策略可以平滑的把副本放置在集群中的机器上,在组件故障是容易实现负载均衡。然而,这个策略提高了写文件的成本,因为每次写操作都需要把文件块传输到多个机架。

通常情况下,当副本因子参数设为3的时候,HDFS放置的策略是吧一个副本放到同一个机架上的节点上,另外两个放到跟这个机架不同的同一个机架的两个不同节点上。这策略节省了跨机架的流量,提升了写文件的性能。机架出故障的概率远小于一个节点出故障的概率,因而该策略没有影响数据的可靠性和可用性。它减少了在读数据的时候网络带宽的使用,因为一个文件块放置在了两个不同的机架上,而不是说那个。在此策略下,文件的复制不会平滑的分布到不同的机架上。 1/3的副本在同一个节点上,2/3的副本在同一个机架上, 另外的1/3平滑的分布在剩余的机架上。该策略提高了写的性能,但并没有牺牲数据的可靠性和读取的性能。

副本的选择

为了减少带宽的使用和读取的延迟,HDFS尽量读取跟reader接近的副本。同节点,同机架,同机房的副本优先读取。

安全模式

启动的时候,NameNode进入一个安全模式。在安全模式中,不会进行数据的复制。NameNode从DataNode接收心跳和块汇报信息。 一个块汇报信息包含一个DataNode含有的所有的块的信息。每个块都有一个指定的最少数量的副本。只有当一个块指定的最少数量的副本都报道了,此块才认为是安全复制了。当一定比例的安全复制的块报道了,再过30秒后,NameNode退出安全模式。然后,它检查所有尚未安全复制的块,进而复制。

文件系统元数据的持久化

NameNode存储了HDFS的名子空间。NameNode用一个事务记录(EditLog)来持久性地记录文件系统的每一次改变。 比如,在HDFS中新建一个文件时,NameNode会在EditLog中插入一条记录。同样,改变复制参数也会在EditLog中增加一条记录。NameNode会在本地文件系统中存储EditLog。整个文件系统的名字空间,包含文件块和文件的映射,以及文件系统给的属性,保存在一个叫FsImage的文件中,同样存储于本地文件系统中。

NameNode在内存中维护着整个文件系统命名空间的文件块映射。关键元数据有较紧凑的设计,比如, 一个4GB的RAM可以存储大量的文件和目录。当NameNode启动的时候,它先读取FsImage和EditLog,把所有的事务施加到FsImge上。 然后,存储一个新的FsImge。然后丢掉旧的EditLog,因为之前所有的事务都已经固化到FsImage中。这个过程成为一个checkpoint. 目前的实现,checkpoint只在NameNode 启动的时候执行。周期性的checkpoint是以后要实现的功能。

DataNode在本地文件系统中存储HDFS数据。DataNode没有HDFS文件的概念,它只是在本地文件系统中保存了每个文件块的数据。DataNode不会在同一个目录中创建所有的文件,而是用启发式的确定每个目录有多少个文件合适。当一个DataNode启动的时候,它首先扫描本地的文件系统,生成一个含所有HDFS数据块的列表发送给NameNode,这就是块报告 BlockReport

通讯协议

所有的HDFS通讯协议基于TCP/IP. 一个客户端通过一个可配置的TCP端口号与NameNode机器建立连接协议是 ClientProtocol。 DataNode和NameNode之间的协议是DataNode protocol。 一个RPC抽象隐藏了这两种协议。 NameNode从不会发起RPC请求,总是响应来自于DataNode和客户端的请求。

健壮性

HDFS组要的目标是实现数据存储的可靠性,即使在发生故障的时候。这里主要说三种故障: NameNode故障, DataNode故障, 和网络分割 partitions。

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

每个DataNode为周期性地给NameNode发送心跳信号。 一个网络故障能引起一组DataNode失去跟NameNode的连接。NameNode检测到这种情况,标记响应的DataNode为失效,后面就不会转发新的Io请求道失效的DataNode上去了。任何在失效的DataNode上的数据都不能访问了。 失效的DataNode可能会导致一些文件块的复制因子远小于指定的值,这时,NameNode 会触发新的复制。重新复制的必要性有多种原因: 一个DataNode不能访问了,一个副本损坏了,一个硬盘出故障了,或者一个文件的复制因子提高了

集群再平衡

HDFS架构跟数据的再平衡是兼容的。数据可能从一个DataNode移动到另外一个,如果剩余的空间到了一定的门槛。对某个文件的读取请求突然大幅提升的时候,更多的副本可能会创建出来。这些还没实现呢。

数据完整性

从DataNode中提取的数据可能是损坏的。原因可能是存储设备的故障,网络问题,或者软件问题。HDFS客户端实现对HDFS数据的校验。当客户端创建一个HDFS时,它会为每一个块算一个校验码,并把校验码存储在一个单独的隐藏的文件中。当客户端取得文件内容时,校验码会重新计算,并跟之前存储的校验码比较。如果不一致,客户端就从另外一个DataNode读取数据块。

元数据磁盘故障

FSImge和EditLog 是HDFS的中心数据结构。这两个文件出问题,会使得HDFS实例出问题。处于这样的原因,NameNode能配置成支持维护多个FsImage和EditLog。 任何的FsImage、EditLog的更改,都同步到其他的副本上去。这种同步可能会降低HDFS的性能,然而,这是可以接受的,因为HDFS是大量数据操作,而不是大量元数据操作。当NameNode启动时,他选择最近的一致的FsImage和EditLog使用。

在2.6 时, NameNode仍旧是single point of failure

快照

HDFS目前不支持Snapshot

数据的组织:

数据块

HDFS设计支持非常大的文件。使用HDFS的应用会处理非常大的数据。这些应用一次写好数据后,读取多次,而且需要这些读取有流式读取的速度。HDFS 支持一次写,多次读。一个典型的块尺寸是64M。 因此,HDFS文件被分割成64M的块,分部在不同的DataNode上。

Staging 分布

一个客户端要求创建一个文件并不能立即能够访问到NameNode。实际上,HDFS首先把文件数据缓存到本地的临时文件中。应用的写操作被重定向到这些临时文件。当本地文件大小达到一个数据块的尺寸的时候,客户端对NameNode发起请求。NameNode把文件名字放到文件层级中,并分配一个文件块。 NameNode回复客户端,返回的数据包含DataNode的标志和目标数据块。然后客户端把数据从临时文件存储到DataNode上。 当一个文件关闭的时候,剩余的尚没有写入文件块的临时文件中的数据会被转移到DataNode中。客户端然后告诉NameNode文件关闭了。这时,NameNode把文件的创建操作固定下来。如果NameNode出故障先于文件关闭,文件就丢失了。

选择上面的方法经过了对运行于HDFS的应用的深思熟虑。 这些应用需要流式写操作到文件。如果一个文件直接写一个远程文件,没有客户端的缓存,那么,网络速度和拥塞会影响写入操作的吞吐量。当然,这个方法也不是首创的,早先的分布式文件系统, AFS,已经用客户端缓存来提高性能。 为了实现数据传输更高的性能,POSIX规范没有完全遵守。

复制的流水线

当一个客户端写数据到HDFS文件中是,像上文介绍的,数据先写到一个本地文件中。加入HDFS文件有个复制参数为3。当本地文件积累到一个块的数据后,客户端从NameNode获取一组DataNode信息。客户端就把数据写到第一个DataNode。第一个DataNode开始接收数据,一部分一部分的,先写到当地的文件,然后把数据转移到第二个DataNode。第二个DataNode如法炮制。最后,第三个DataNode把数据写入本地文件系统。所以,一个DataNode可以从流水线中前面的DataNode接收数据,同时,把数据转发到流水线中的另外DateNode。

可访问性

应用程序可以用多种方式访问HDFS中的数据。原生的,HDFS提供了文件系统JavaAPI http://hadoop.apache.org/docs/current/api/. C语言的包转也有。而且,HTTP浏览器也可以浏览HDFS中的文件。 WebDAV协议的支持正在构建之中。

FS Shell

HDFS可以让用户数据组织为文件和目录。它提供了一个命令行的接口,叫做FS Shell。用户可以通过FS Shell与HDFS中的数据交互。 语法于其他shell 类似。

创建 /foodir             bin/hadoop dfs –mkdir /foodir

删除/foodir              bin/hadoop dfs –rmr /foodir

看一个文件内容 /foodir/myfile.txt       bin/hadoop dfs –cat /foodir/myfile.txt

FS Shell 主要为脚本语言用来与存储的数据交互。

DFSAdmin

DFSAdmin命令主要管理HDFS集群。 这些命令是HDFS管理员使用的。

把集群置于安全模式              bin/hadoop dfsadmin –safemode enter

生成DataNode的列表           bin/haddop dfsadmin –report

刷新DataNode                          bin/haddop dfsadmin –refershNodes ???

浏览器接口

通常HDFS会配置一个网络服务器,通过一个TCP端口可以访问HDFS命名空间。 用户可以通过浏览器浏览HDFS目录,产看文件内容

空间回收

文件删除和反删除

当用户或者应用删除一个文件时,文件并不会立即从HDFS中删除。而是,先被重命名到/trash目录。只要它还在transh目录,就可以很快恢复。留在该目录中的时间可以配置。时间过了后,NameNode从名字空间中删除。进而跟文件对应的文件块释放。需要注意的是,从一个文件被是用户删除到HDFS系统空间增加会有相当的延迟。

用户可以恢复一个文件,只要它还在/trash目录中。方法是进入/trash 目录,访问文件。Core-site.xml中的fs.trash.interval 参数控制着文件在/trash目录中的时间。

降低副本因子

当副本因子减小的时候,NameNode选择可以删除的多出来的副本。下一次心跳的时候,就把这个信息传递到DataNode。DateNode就删除相对应的文件块。

References

Hadoop JavaDoc API.

HDFS source code: http://hadoop.apache.org/version_control.html

原文地址:https://www.cnblogs.com/restart/p/4422080.html