HDFS 被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统,是 Hadoop 应用程序使用的主要分布式存储。HDFS 与现有的分布式文件系统有许多相似之处;但是,与其他分布式文件系统的区别也是很明显的。HDFS 具有高度的容错能力,旨在部署在低成本硬件上;HDFS 提供对应用程序数据的高吞吐量访问,并且适用于具有大数据集的应用程序;HDFS 放宽了一些POSIX要求,以实现对文件系统数据的流式访问。

0x00 HDFS 架构

HDFS (Hadoop Distributed File System) 采用的是 Master/Slave 架构,一个 HDFS 集群包含一个单独的 NameNode 和多个 DataNode 节点,如下图所示:

HDFS 架构

主要由以下几个组件构成:

  • NameNode
  • Secondary NameNode
  • DataNode
  • Client

需要说明的是:类似于磁盘 Block size 概念,Hadoop 集群中文件的存储都是以块的形式存储在 HDFS 中。通过设置 hdfs-site.xml 文件中 dfs.blocksize 参数来配置块大小,默认是128M。

0x01 文件写入过程

HDFS 文件写入过程

Client 向 HDFS 写入文件的具体过程如下:

  1. Client 调用 DistributedFileSystem 对象的 create 方法,创建一个文件输出流(FSDataOutputStream)对象;

  2. 通过 DistributedFileSystem 对象与集群的 NameNode 进行一次 RPC 远程调用,在 HDFS 的 Namespace 中创建一个文件条目(Entry),此时该条目没有任何的 Block,NameNode 会返回该数据每个块需要拷贝的 DataNode 地址信息;

  3. 通过 FSDataOutputStream 对象,开始向 DataNode 写入数据,数据首先被写入 FSDataOutputStream 对象内部的数据队列中,数据队列由 DataStreamer 使用,它通过选择合适的 DataNode 列表来存储副本,从而要求 NameNode 分配新的 block;

  4. DataStreamer 将数据包以流式传输的方式传输到分配的第一个 DataNode 中,该数据流将数据包存储到第一个 DataNode 中并将其转发到第二个 DataNode 中,接着第二个 DataNode 节点会将数据包转发到第三个 DataNode 节点;

  5. DataNode 确认数据传输完成,最后由第一个 DataNode 通知 client 数据写入成功;

  6. 完成向文件写入数据,Client 在文件输出流(FSDataOutputStream)对象上调用 close 方法,完成文件写入;

  7. 调用 DistributedFileSystem 对象的 complete 方法,通知 NameNode 文件写入成功,NameNode 会将相关结果记录到 editlog 中。

0x02 文件读取过程

HDFS 文件读取过程

Client 向 HDFS 读取文件的具体过程如下:

  1. Client 通过 DistributedFileSystem 对象与集群的 NameNode 进行一次 RPC 远程调用,获取文件 block 位置信息;

  2. NameNode 返回存储的每个块的 DataNode 列表;

  3. Client 将连接到列表中最近的 DataNode;

  4. Client 开始从 DataNode 并行读取数据;

  5. 一旦 Client 获得了所有必须的 block,它就会将这些 block 组合起来形成一个文件。

在处理 Client 的读取请求时,HDFS 会利用机架感知选举最接近 Client 位置的副本,这将会减少读取延迟和带宽消耗。

0x03 HDFS 遗留问题

在前面的介绍中,关于 HDFS 1.0 架构的设计缺陷主要有以下两点:

  • NameNode 的单点问题,如果 NameNode 挂掉了,数据读写都会受到影响,HDFS 整体将变得不可用,这在生产环境中是不可接受的;

  • 水平扩展问题,随着集群规模的扩大,1.0 时集群规模达到3000时,会导致整个集群管理的文件数目达到上限(因为 NameNode 要管理整个集群 block 元信息、数据目录信息等)。

为了解决上面的两个问题,Hadoop2.0 提供一套统一的解决方案:

  • HA(High Availability 高可用方案):这个是为了解决 NameNode 单点问题;

  • NameNode Federation:是用来解决 HDFS 集群的线性扩展能力。

参考文献

HDFS Users Guide
HDFS Architecture
Hdfs block数据块大小的设置规则
HDFS基础架构与各个组件的功能
HDFS 架构学习总结
HDFS 原理、架构与特性介绍