在大数据开发学习路径中,HDFS(Hadoop Distributed File System) 是最核心的基础。它不仅负责存储海量数据,还保证了分布式环境下的数据高可用与容错性。HDFS是Google File System的开源版本,下面是大数据三驾马车之一的Google File System的论文pdf链接

Google File System Paper

本文将从整体架构、数据读写流程、NameNode 解析以及 DataNode 解析四个方面,深入剖析 HDFS 的工作原理。

概述

随着据量越来越大,在一个操作系统存不下所有的数据,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,迫切需要一种系统来管理多台机器上的文件,这就是分布式文件管理系统,HDFS就是分布式文件管理系统中的一种。

HDFS适合一次写入,多次读出的场景(Why?)

         -> HDFS不支持并发写入和随机写入

         -> 强制一次性写入使得系统无需关注数据一致性,并且实现了简单的元数据管理和高吞吐数据写入

HDFS优点:高容错性,支持的数据规模和文件规模适合处理大数据,可构建在廉价机器之上(副本策略提高可靠性)

HDFS缺点:不支持文件的并发写入,不适合低延时数据访问,对大量小文件的存储低效

   

整体架构

HDFS 是一个 主从架构 的分布式文件系统,由以下组件构成:

  • NameNode(NN):存放元数据(文件路径、文件到数据块的映射、块副本位置)。

  • Secondary NameNode(2NN):辅助 NN,做 FsImage + EditLog 合并,并不是真正的热备。

  • DataNode(DN):实际存储数据块,并向 NameNode 汇报心跳与块信息。

  • Client:客户端,负责读写数据。

Apache Hadoop官网的HDFS架构图

数据读写流程

HDFS写数据

HDFS写数据流程:

        -> Client向NameNode发出写数据的请求,NameNode响应回复Client

        -> Client向NameNode发出请求上传第一个Block,NameNode回复三个距离最近的DataNode

        -> Client拿到具体节点之后向DN1->DN2->DN3请求建立传输通道,DataNode应答

        -> 建立起传输通道之后向DN1传数据,DN1收到之后copy给DN2,DN2copy给DN3

        -> 如果文件大于一个Block,随后的Block重复上述步骤

那么NameNode如何找到距离最近的DataNode,距离又如何计算?

节点距离:两个节点到达最近的共同祖先的距离总和。 

那对于副本的DataNode位置又是怎么选择的?

一般来说第一副本找到后,第二第三副本将会存储在另一个机架上的不同节点,保证速率

那么Hadoop又是如何感知到机架的,明确每一个DataNode具体位置的?

        机架感知就是让 Hadoop 知道每个 DataNode 所在的机架位置,从而在副本放置、任务调度时,尽量减少跨机架通信,提高性能和可靠性。

        Hadoop 通过一个 脚本 来识别 IP → 机架的映射,通过输入主机名/IP来返回机架路径。

hadoop102 → /rackA

hadoop103 → /rackA

hadoop104 → /rackB

        这个脚本路径位于core-site.xml配置文件中:

<property>
    <name>topology.script.file.name</name>
    <value>/etc/hadoop/conf/topology.sh</value>
</property>

   当DataNode启动并注册到NameNode中时候,NameNode就会调用这个脚本确定节点机架的位置。

HDFS读数据

HDFS读数据流程:

        -> Client发送读取数据的请求,NameNode接收后进行元数据查询,将元数据返给Client

        -> Client收到元数据后找到存数据的DataNode,找一台距离最近的DataNode发读数据请求

        -> DataNode开始传数据,以Package为单位,Client接受先写入内存,再写入目标文件

NameNode解析

通过从我们现实会遇到的问题出发,我们就会更清楚的理解设计者这样设计的原因与意义。        

        NameNode的元数据会被随机访问,还有响应时间的要求,所以不能存到磁盘中,需要存储到内存中  

----> 内存如果断电就会数据丢失,所以要有数据备份,于是产生了FsIamge

----> 如果每一次元数据更新都更新FsImage的话效率太低,不更新又会产生数据一致性的问题,而且如果NameNode断电将造成部分数据永久性的丢失,所以追加设计了Edits文件,将操作放入Edits文件,再定时合并FsImage与Edits。

----> 但是数据量巨大的时候每个操作均写入Edits就会造成空间问题,同时恢复数据的时间过长,所以Hadoop设计了SecondaryNamenode来专门定时进行FsImage与Edits的合并问题。

于是我们得到了现在的NameNode设计架构

        如图是NameNode的工作机制,非常清晰

DataNode解析

工作机制

  • 每个 DN 负责存储 HDFS 的实际数据块(写在磁盘中,包括数据本身与元数据)。

  • 定期向 NN 发送 心跳(默认 3 秒一次),表明自己存活。

  • 定期发送 块报告(默认 6 小时一次),汇报自己存储的块信息。

数据完整性

如果出现磁盘损坏等情况导致数据完整性受损,就会引发很多严重问题,所以数据完整性的查验非常重要。

        当DataNode读取Block的时候,它会计算CheckSum(校验和)。

----> 如果计算后的CheckSum,与Block创建时值不一样,说明Block已经损坏。

----> Client将会读取其他DataNode上的Block。

----> DataNode在其文件创建后周期验证CheckSum。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐