干货满满,图文详解 HDFS 的 工作机制 及其原理

HDFS 是基于 流数据 访问模式的 分布式 文件系统(HDFS放宽了一部分 POSIX约束 ,来实现 流式读取 文件系统数据的目的),支持存储 海量 的数据,可以运行在 低成本 的硬件上。其提供 高吞吐量 、高容错性 的数据访问,非常适合大规模数据集上的应用。了解 HDFS 的工作机制,可以加深我们对分布式系统的理解,以及增强遇到问题时的分析解决能力,以下介绍下 HDFS 的工作机制。

如果想了解 HDFS ,可以参考这篇文章:HDFS 及其组成框架介绍

HDFS 的工作机制

一、 机架感知

1.1 设计机架感知的目的

机架感知的设计,考虑到两个方面:

  1. 不同节点之间的通信,希望在同一机架内进行(Hadoop集群会分布在很多机架上),而不是跨机架;
  2. 为了提高 容错 能力,NameNode (名称节点)会尽可能把 数据块的副本 放在多个机架上。

1.2 通过网络拓扑图分析

1.2.1 网络拓扑图介绍

DataNode 的网络拓扑图如下:
《干货满满,图文详解 HDFS 的 工作机制 及其原理》
如上图,D1、R1是交换机,最底层是 DataNode 。可执行脚本文件返回各 DataNode 的机架 ID ,即 RackID(比如,H1 的 parent 是R1,R1的 parent 是D1,则 H1 的 RackID=/D1/R1/H1)。

有了这些 RackID 信息,就可以计算任意两台 DataNode 之间的距离了:

distance(/D1/R1/H1,/D1/R1/H1)=0    //相同的 DataNode
distance(/D1/R1/H1,/D1/R1/H2)=2    //同一个 Rack 下不同的 DataNode
distance(/D1/R1/H1,/D1/R1/H4)=4    //同一 IDC 下不同的 DataNode
distance(/D1/R1/H1,/D2/R3/H7)=6    //不同 IDC 下的 DataNode

IDC是互联网数据中心,可以理解为机房。

1.2.2 功能分析

默认情况下,HDFS 不能 自动判断 集群中各个 DataNode 的网络拓扑情况,集群 默认都 处在同一个机架名为 /default-rack的机架上(在这种情况下,任何一台 DataNode 机器,不管在物理上是否是属于同一个机架,都会被认为是在同一个机架下)。

通常,我们通过 外在脚本 实现机架感知,需要配置 net.topology.script.file.name属性(属性值一般是一个可执行脚本文件的路径)。脚本接收一个值,再输出一个值(一般都是接收 IP地址 ,输出这个地址所对应的 机架信息 )。

二、 副本冗余存储策略

HDFS 上的文件对应的数据块保存有多个副本(默认保存3个副本),且提供 容错机制 ,副本 丢失 或 宕机(即 死机) 时自动恢复。

2.1 策略的介绍

下面,以保存 3个副本 为例:
《干货满满,图文详解 HDFS 的 工作机制 及其原理》

  1. 第一个副本(副本一):放置在 上传文件 的数据节点上(若是在 集群外 提交,则随机挑选一个 CPU比较空闲磁盘不太满 的节点)。
  2. 第二个副本(副本二):放置在与第一个副本 不同 的机架的节点上。
  3. 第三个副本(副本三):放置在与第二个副本 相同 机架的其他节点上。
  4. 如果有 更多 副本,那么这些副本 随机选择 节点存放。

需要注意的是,副本并不都是均匀分布在不同的机架上

2.2 策略的优点

副本冗余存储策略,主要有三个优点:

  1. 减少了机架间的 数据传输 ,提高了写操作的效率。(不会影响数据的可靠性和可用性,因为机架的错误远远比节点的错误小)
  2. 减少了 读取数据 时所需的网络传输总带宽。(因为数据块只放在两个不同的机架上)
  3. 在不损害数据 可靠性 和 读取性能 的情况下,改进了写操作的性能。(一个副本在一个机架的一个节点上,另外两个副本在另一个机架的不同节点上,其他副本则 均匀分布 在剩下的机架中。如 2.1 所介绍。)

三、 文件传输过程

在 HDFS 中 读写数据 的过程都是通过数据流完成的。HDFS 提供了数据流的 I/O操作类(包括 FSDataInputStream 和 FSDataOutputStream )

3.1 文件读取

3.1.1 读取过程分析

HDFS 文件读取(即 数据下载)过程如图所示:
《干货满满,图文详解 HDFS 的 工作机制 及其原理》

⑴ HDFS 客户端通过 DistributeFileSystem 对象的 open() 方法打开需要读取的文件。

⑵ DistributeFileSystem 向远程的 NameNode 节点发起 RPC调用 ,得到文件的数据块信息,返回数据块列表。(对于每个数据块,NameNode 返回该数据块的 DataNode 地址)

⑶ DistributeFileSystem 返回一个 FSDataInputStream 对象给客户端,客户端调用 FSDataInputStream 对象的 read() 方法读取数据。

⑷ 通过对数据流反复调用 read() 方法,把数据从数据节点传输到客户端。

⑸ 当一个节点的数据读取完毕时, DFSInputStream 对象会关闭与此数据节点的连接,然后连接此文件 下一个数据块 的最近数据节点。

⑹ 当客户端读取完数据时,调用 FSDataInputStream 对象的 close() 方法关闭输入流。

3.1.2 FSDataInputStream 类介绍

FSDataInputStream 输入流类的常用方法:

方法名返回值作用
read(ByteBuffer buf)int读取并写入 buf 缓冲区,返回所读的字节数
read(long pos,byte[] buf,int offset,int len)int从输入流的指定位置开始,把数据读入缓冲区。
readFully(long pos,byte[] buf)void从指定位置开始,读取所有数据到缓冲区
seek(long offset)void指向输入流的第 offset 字节
releaseBuffer(ByteBuffer buf)void删除指定的缓冲区

pos 指定从输入流中读取数据的位置;offset 指定数据写入缓冲区的位置(偏移量);len 指定读操作的最大字节数。

3.2 文件写入

3.2.1 写入过程分析

HDFS 文件写入(即 数据上传)过程如图所示:
《干货满满,图文详解 HDFS 的 工作机制 及其原理》

⑴ 客户端调用 DistributedFileSystem 对象的 create() 方法创建一个文件输出流对象。

⑵ DistributedFileSystem 对象远程的 NameNode 节点发起一次 RPC调用 ,NameNode 检查这个文件 是否存在 ,以及客户端 是否有权限 新建文件。

⑶ 客户端调用 FSDataOutputStream 对象的 write() 方法写数据(数据鲜卑写入缓冲区,再被切分为一个个数据包)。

⑷ 每个数据包被发送到由 NameNode 节点分配的一组数据节点中的一个数据节点上,在这组数据节点组成的管道上依次传输数据包。

⑸ 管道上的节点按反向顺序返回确认信息,最终由管道的第一个数据节点将整条管道的确认信息发送给客户端。

⑹ 客户端完成写入,调用 close() 方法关闭文件输出流。

⑺ 通知 NameNode 文件写入成功。

3.2.2 FSDataOutputStream 类介绍

FSDataOutputStream 输入流类的常用方法:

方法名返回值作用
write(byte[] b)void将数组 b 中的所有字节写入输出流
write(byte[] buf,int off,int len)void将字节组写入底层输出流,写入的字节从 off 偏移量开始,写入长度为 len
flush()void刷新数据输出流(缓冲区内容被强制写入流中)

len 指定读操作的最大字节数。

四、 数据容错

HDFS 能够在出错的情况下,保证 数据存储 的可靠性。常见的出错情况有 NameNode 节点出错DataNode 节点出错数据出错 这三种情况。

4.1 分析 NameNode 节点出错

HDFS 中所有元数据都保存在 NameNode (名称节点)上,NameNode 节点维护 edits 和 fsimage 这两个文件。(如果这两个文件损坏,HDFS 就会 失效 )

Hadoop 提供了两个机制,来确保 NameNode 的安全:

  1. 把 NameNode 节点上的元数据信息同步存储到其他文件系统(比如 NFS ),当 NameNode 出现故障时,HDFS 自动切换到备用的 NameNode 上(HDFS HA ,就是采用共享存储系统来存储 edits 的)。
  2. 运行一个 SecondaryNameNode 节点,当 NameNode 宕机时,利用 SecondaryNameNode 的元数据信息进行系统恢复(仍然会有 部分数据 丢失)。
    通常,这 两个方法 结合使用。

4.2 分析 DataNode 节点出错

NameNode 通过 心跳信号 来检测近期不发送心跳信号的 DataNode,并将其标志为 宕机 (每个 DataNode 周期性地向 NameNode 发送心跳信号),不再发送 新的 I/O请求 给它们。

数据块需要重新复制的情况:

  1. 某个 DataNode 节点丢失;
  2. DataNode 上的硬盘出错;
  3. 某个副本损坏;
  4. 某个数据块的副本系数低于设定值。

4.3 分析 数据出错

从 DataNode 获取的数据块,有可能本身就是损坏的(比如可能是因为 网络错误 、软件bug 或者 DataNode的存储设备错误)。

HDFS 使用 校验和来判断数据块是否损坏。HDFS 的每个 DataNode 节点,保存了检测校验的日志(客户端的每一次检验都会被记录)。

如果文章对您有帮助,请点个,留给评论支持一下,若有疑问可以私信留言。如果能给个三连(点赞收藏关注 )就最好啦。

    原文作者:苜苜的烂笔头
    原文地址: https://blog.csdn.net/qq_45069279/article/details/114734679
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞