购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.1 HDFS简介

HDFS(Hadoop Distributed File System)是Hadoop项目的核心子项目,在大数据开发中通过分布式计算对海量数据进行存储与管理。它基于流数据模式访问和处理超大文件的需求而开发,可以运行在廉价的商用服务器上,为海量数据提供了不怕故障的存储方法,进而为超大数据集的应用处理带来了很多便利。

下面是HDFS的一些显著特征:

4.1.1 设计目标

HDFS的主要设计目标如下。

1. 硬件故障

硬件故障是常态,而非例外。HDFS集群可能由数百或数千台服务器组成,每台服务器都存储文件系统数据的一部分,且每台服务器都有很大的故障概率。因此,故障检测和快速、自动地从故障中恢复是HDFS的核心架构目标。

2. 流式数据访问

在HDFS上运行的应用程序需要对其数据集进行流式访问,这与运行在一般文件系统上的应用不同。HDFS更适合批量处理,而不是用户的交互使用,它更加强调数据访问的高吞吐量,而不是数据访问的低延迟。

3. 大型数据集

HDFS是一个支持大型数据集的文件系统,一个典型的HDFS数据文件可以从千兆字节到兆兆字节不等,可以为具有数百个节点的集群提供高聚合的数据带宽和规模,同时承载千万个文件。

4. 简单一致性模型

HDFS遵循简单一致性模型,一次写入,多次读取。即文件一旦被建立、写入、关闭,就不能被改变,更不能从文件任意位置进行修改,以此来保证数据的一致性。Hadoop 2.x以后,支持在文件末尾追加内容。

5. 移动计算比移动数据容易

HDFS被设计为能更好地将计算迁移到更接近数据的位置,而不是将数据移动到应用程序运行的位置,这样应用程序的计算效率会更高。HDFS为应用程序提供接口,使其更接近数据所在的位置。

6. 平台的可移植性

HDFS被设计为可以从一个平台轻松地移植到另一个平台,从而使HDFS能够作为大型应用程序的首选平台。

4.1.2 总体架构

HDFS是使用Java语言构建的系统,任何支持Java的计算机都可以运行HDFS,HDFS集群的总体架构如图4-1所示。

图4-1 HDFS集群的总体架构

HDFS是一个典型的主/从(Master/Slave)架构的分布式系统。一个HDFS集群由一个元数据节点(称为NameNode)和一些数据节点(称为DataNode)组成。NameNode是HDFS的主节点,是一个用来管理文件元数据(文件名称、大小、存储位置等)和处理来自客户端的文件访问请求的主服务器;DataNode是HDFS的从节点,用来管理对应节点的数据存储,即实际文件数据存储于DataNode上,而DataNode中的数据则保存在本地磁盘。

当HDFS系统启动后,NameNode上会启动一个名称为“NameNode”的进程,DataNode上会启动一个名称为“DataNode”的进程。

典型的HDFS集群部署是有一台专用的计算机只运行NameNode进程,集群中的其他计算机都运行DataNode进程。HDFS架构并不排除在同一台计算机上运行多个DataNode进程,但在实际部署中很少出现这种情况。

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

此外,还有一个重要组件称为SecondaryNameNode,4.1.3节将对HDFS各组件进行详细讲解。

4.1.3 主要组件

HDFS系统的主要构成组件如下。

1. 数据块(Block)

HDFS中的文件是以数据块(Block)的形式存储的,默认最基本的存储单位是128 MB(Hadoop 1.x为64 MB)的数据块。也就是说,存储在HDFS中的文件都会被分割成128 MB一块的数据块进行存储,如果文件本身小于一个数据块的大小,则按实际大小存储,并不占用整个数据块空间。

HDFS的数据块之所以会设置这么大,其目的是减少寻址开销。数据块数量越多,寻址数据块所耗的时间就越多。当然也不会设置过大,MapReduce中的Map任务通常一次只处理一个块中的数据,如果任务数太少,作业的运行速度就会比较慢(MapReduce将在第5章讲解)。

HDFS的每一个数据块默认都有三个副本,分别存储在不同的DataNode上,以实现容错功能。因此,若数据块的某个副本丢失并不会影响对数据块的访问。数据块大小和副本数量可在配置文件中更改。HDFS数据块的存储结构如图4-2所示。

图4-2 HDFS数据块的存储结构

2. NameNode

NameNode是HDFS中存储元数据(文件名称、大小和位置等信息)的地方,它将所有文件和文件夹的元数据保存在一个文件系统目录树中,任何元数据信息的改变,NameNode都会记录。HDFS中的每个文件都被拆分为多个数据块存放,这种文件与数据块的对应关系也存储在文件系统目录树中,由NameNode维护。

NameNode还存储数据块到DataNode的映射信息,这种映射信息包括:数据块存放在哪些DataNode上、每个DataNode上保存了哪些数据块。

NameNode也会周期性地接收来自集群中DataNode的“心跳”和“块报告”。通过“心跳”与DataNode保持通信,监控DataNode的状态(活着还是宕机),若长时间接收不到“心跳”信息,NameNode会认为DataNode已经宕机,从而做出相应的调整策略。“块报告”包含了DataNode上所有数据块的列表信息。

3. DataNode

DataNode是HDFS中真正存储数据的地方。客户端可以向DataNode请求写入或读取数据块,DataNode还在来自NameNode的指令下执行块的创建、删除和复制,并且周期性地向NameNode汇报数据块信息。

4. SecondaryNameNode

SecondaryNameNode用于帮助NameNode管理元数据,从而使NameNode能够快速、高效地工作。它并不是第二个NameNode,仅是NameNode的一个辅助工具。

HDFS的元数据信息主要存储于两个文件中:fsimage和edits。fsimage是文件系统映射文件,主要存储文件元数据信息,其中包含文件系统所有目录、文件信息以及数据块的索引;edits是HDFS操作日志文件,HDFS对文件系统的修改日志会存储到该文件中。

当NameNode启动时,会从文件fsimage中读取HDFS的状态,也会对文件fsimage和edits进行合并,得到完整的元数据信息,随后会将新HDFS状态写入fsimage。但是在繁忙的集群中,edits文件会随着时间的推移变得非常大,这就导致NameNode下一次启动的时间会非常长。为了解决这个问题,则产生了SecondaryNameNode,SecondaryNameNode会定期协助NameNode合并fsimage和edits文件,并使edits文件的大小保持在一定的限制内。SecondaryNameNode通常与NameNode在不同的计算机上运行,因为它的内存需求与NameNode相同,这样可以减轻NameNode所在计算机的压力。

SecondaryNameNode的工作流程如图4-3所示。

图4-3 SecondaryNameNode的工作流程

首先,当SecondaryNameNode准备从NameNode上获取元数据时,会通知NameNode暂停对文件edits的写入。NameNode收到通知后,会停止写入edits文件,而是将新的操作日志信息写入到一个新的文件edits.new中。

然后,SecondaryNameNode通过http get方式将NameNode的元数据文件edits和fsimage获取到本地,并将其合并为一个新的文件fsimage.ckpt。

最后,SecondaryNameNode把新的文件fsimage.ckpt通过http post方式发回NameNode。NameNode收到SecondaryNameNode发回的新文件fsimage.ckpt后,用该文件覆盖掉原来的fsimage文件,并删除原有的edits文件,同时将文件edits.new重命名为edits,将文件fsimage.ckpt重命名为fsimage。

上述操作避免了NameNode日志的无限增长,从而加速了NameNode的启动过程。

4.1.4 文件读写

如图4-4所示,当客户端需要读取文件时,首先向NameNode发起读请求,NameNode收到请求后,会将请求文件的数据块在DataNode中的具体位置(元数据信息)返回给客户端,客户端根据文件数据块的位置,直接找到相应的DataNode发起读请求。

图4-4 HDFS读数据流程

如图4-5所示,当客户端需要写文件时,首先向NameNode发起写请求,将需要写入的文件名、文件大小等信息告诉NameNode。NameNode会将文件信息记录到本地,同时会验证客户端的写入权限,若验证通过,会向客户端返回文件数据块能够存放在DataNode上的存储位置信息,然后客户端直接向DataNode的相应位置写入数据块。被写入数据块的DataNode也会将数据块备份到其他DataNode上。

图4-5 HDFS写数据流程

举个例子,我们可以把NameNode想象成是一个仓库管理员,管理仓库中的商品;DataNode想象成是一个仓库,用于存储商品,而商品就是我们所说的数据。仓库管理员只有一个,而仓库可以有多个。当需要从仓库中获取商品时,需要先询问仓库管理员,获得仓库管理员的同意,并且得到商品所在仓库的具体位置(例如,在1号仓库的1号货架上),然后根据位置信息直接去对应的仓库中的相应货架上取得商品。当需要向仓库中存入商品时,同样需要先询问仓库管理员,获得仓库管理员的同意,并且得到仓库管理员提供的商品能够存放的具体位置,然后根据位置信息直接去对应的仓库中的相应货架上存入商品。

此外,用户可以使用多种客户端接口对HDFS发起读/写操作,包括命令行接口、代码API接口和浏览器接口,使用非常方便,而不需要考虑HDFS的内部实现。本章后续将详细讲解HDFS各种接口的使用。 /m6f0CCmN39H8RGComPv3zn2+CNV63LYc6V3dX0PxYgFd0/gcD0kP/sRa2OEoJs3

点击中间区域
呼出菜单
上一章
目录
下一章
×