谈到大数据,不得不提的一个名词是“HDFS”。它是一种分布式文件存储系统,其系统架构图如下图所示:

hdfs 元数据缺失 hdfs元数据是什么_HDFS


从图中可以了解到的几个关键概念

  • 元数据(MetaData)
  • 机架(Rock)
  • 块(Block)

从图中可以了解到的两个重要组件:

  • NameNode
  • DataNode

需要了解的另一个组件:

  • SecondaryNameNode

三个重要的组件说明

NameNode

简单地说,NameNode 有管理存储两个作用。NameNode 管理文件系统的命名空间,维护文件系统树以及树中的所有文件和目录。它存储的是元数据(Metadata)信息,包括文件名目录以及它们之间的层级关系、文件目录的所有者及其权限、每个文件块的名以及文件有哪些块组成等。

这里就很容易理解为什么Hadoop倾向存储大文件的原因了:因为文件越小,存储同等大小文件需要的元信息就越多,会给NameNode 带来了存储压力。

在 NameNode 中存放元信息的文件是 fsimage 。在系统运行期间,所有对元信息的操作都需要保存到内存中并持久化到另一个文件 edit logs,我们在讲解 SecondaryNameNode 组件时还会提到这两个文件。

DataNode

DataNode 具有的作用如下:

  • 负责存储数据块(磁盘读写的基本单位),并提供数据块的读写服务。
  • 根据 NameNode 的指示进行创建、删除和复制等操作。
  • 通过心跳机制,定期报告文件块列表信息。
  • 进行 DataNode 之间通信,以及块的副本处理。

SecondaryNameNode

SecondaryNameNode并不是 NameNode 的备份,这点很容易理解错。SecondaryNameNode 是在文件系统中设置一个检查站点帮助 NameNode 更好的工作

这里我们简单梳理一下 NameNode 的加载过程:NameNode 启动时通过 fsimage 文件获取整个文件系统的快照,启动后将对文件系统的改动写到 edit logs 中,SecondaryNameNode 定时去获取 这个 edit logs,并更新到自己的 fsimage 中。一旦有了新的 fsimage,将其再拷贝回 NameNode 中,NameNode下次启动时会使用这个新的 fsimage,这个过程如下图所示:

hdfs 元数据缺失 hdfs元数据是什么_HDFS_02

HDFS 的高可用设计

机架感知策略

机架感知策略简单点说就是副本放置策略。HDFS 中默认一个块具有三个副本,其分布如下图所示:

hdfs 元数据缺失 hdfs元数据是什么_Hadoop_03


第一个副本放在客户端相同的节点上,第二个副本放在不同机架的节点上,第三个副本放在与第二个副本同机架但不同节点上。

容错

我们在讨论容错时,通常关注这四个角度:数据存储故障容错磁盘故障容错DataNode 故障容错以及 NameNode 故障容错。对于这几个角度的容错又可以从三个维度去分析:冗余备份失效转移降级限流。例如:NameNode 的故障检测通过 fsimage 文件和 edit logs文件;数据的故障容错通过冗余备份——机架感知策略等。

HDFS 的特点

HDFS 能够管理和存储PB级别数据,处理非结构化数据,一般对数据的及时性要求不高,通常适合 write-once-read-many 存取模式。

HDFS 不建议存储小文件,不建议大量随机读,不支持多用户写入以及不支持对文件的修改。

HDFS 写流程

hdfs 元数据缺失 hdfs元数据是什么_hdfs 元数据缺失_04


客户端调用 create()来创建文件,Distributed File System 用 RPC 调用 NameNode 节点,在文件系统的命名空间中创建一个新的文件。NameNode 节点首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件。

Distributed File System 返回 DFSOutputStream,客户端用于写数据。客户端开始写入数据,DFSOutputStream 将数据分成块,写入 Data Queue。Data Queue 由 Data Streamer 读取,并通知 NameNode 节点分配数据节点,用来存储数据块(每块默认复制 3 块)。分配的数据节点放在一个 Pipeline 里。Data Streamer 将数据块写入 Pipeline 中的第一个数据节点。 第一个数据节点将数据块发送给第二个数据节点。 第二个数据节点将数据发送给第三个数据节点。

DFSOutputStream 为发出去的数据块保存了 Ack Queue,等待 Pipeline 中的数据节点告知数据已经写入成功。

HDFS 读流程

hdfs 元数据缺失 hdfs元数据是什么_HDFS_05

首先 Client 通过 File System的 Open函数打开文件, Distributed File System用RPC 调用 NameNode 节点,得到文件的数据块信息。

对于每一个数据块,NameNode 节点返回保存数据块的数据节点的地址。Distributed File System 返回 FSDataInputStream 给客户端, 用来读取数据。 客户端调用 stream 的 read()函数开始读取数据。 DFSInputStream 连接保存此文件第一个数据块的最近的数据节点。DataNode 从数据节点读到客户端(client),当此数据块读取完毕时,DFSInputStream 关闭和此数据节点的连接,然后连接此文件下一个数据块的最近的数据节点。当客户端读取完毕数据的时候,调用FSDataInputStream 的 close 函数。

在读取数据的过程中, 如果客户端在与数据节点通信出现错误, 则尝试连接包含此数据块的下一个数据节点。失败的数据节点将被记录,以后不再连接。