HDFS分布式文件系统架构原理详解

简介: HDFS(Hadoop Distributed File System)是Hadoop核心组成之一,是分布式计算中数据存储管理的基础,被设计成适合运行在通用硬件上的分布式文件系统。HDFS架构中有两类节点,一类是NameNode,又叫“元数据节点”,另一类是DataNode,又叫“数据节点”,分别执行Master和Worker的具体任务。HDFS是一个(Master/Slave)体系结构,“一次写入,多次读取”。HDFS的设计思想:分而治之—将大文件、大批量文件分布式存放在大量独立的机器上。

一、HDFS的优缺点


(1)优点

高容错性。数据保存多个副本,通过增加副本的形式提高容错性,某个副本丢失后,它可以通过其它副本自动恢复。

适合大批量数据处理。处理达到GB、TB,甚至PB级别的数据,处理百万规模以上的文件数量,处理10K节点的规模。

流式文件访问。一次写入多次读取,文件一旦写入不能修改,只能追加,保证数据一致性。

可构建在廉价机器上。通过多副本机制提高可靠性,提供容错和恢复机制。


(2)缺点

不适用HDFS的场景:


低延时数据访问。做不到毫秒级存储数据,但是适合高吞吐率(某一时间内写入大量的数据)的场景。

小文件存储。存储大量小文件会占用NameNode大量的内存来存储文件、目录和块信息。

并发写入、随机读写。一个文件不允许多个线程同时写,仅支持数据追加,不支持文件的随机修改。

1.jpeg


二、HDFS架构原理



HDFS架构


NameNode

DataNode

Sencondary NameNode

数据存储细节

2.jpeg


(1)NameNode详解

NameNode:就是 master,它是一个主管、管理者。


管理 HDFS 的名称空间

管理数据块(Block)映射信息

配置副本策略

处理客户端读写请求。

Namenode 的目录结构: ${ dfs.name.dir}/current /VERSION


/edits (操作日志文件)

/fsimage (元数据镜像文件)

/fstime (保存最近一次恢复的时间)

Namenode 上保存着 HDFS 的名字空间。对于任何对文件系统元数据产生修改的操作, Namenode 都会使用一种称为 EditLog 的事务日志记录下来。例如,在 HDFS 中创建一个文件, Namenode 就会在 Editlog 中插入一条记录来表示;同样地,修改文件的副本系数也将往 Editlog 插入一条记录。 Namenode 在本地操作系统的文件系统中存储这个 Editlog 。整个文件系统的名 字空间,包括数据块到文件的映射、文件的属性等,都存储在一个称为 FsImage 的文件中,这 个文件也是放在 Namenode 所在的本地文件系统上。

Namenode 在内存中保存着整个文件系统的名字空间和文件数据块映射(Blockmap) 的映像 。这个关键的元数据结构设计得很紧凑,因而一个有 4G 内存的Namenode 足够支撑大量的文件 和目录。当 Namenode 启动时,它从硬盘中读取Editlog 和 FsImage ,将所有 Editlog 中的事务作 用在内存中的 FsImage 上,并将这个新版本的 FsImage 从内存中保存到本地磁盘上,然后删除 旧的 Editlog ,因为这个旧的 Editlog 的事务都已经作用在 FsImage 上了。这个过程称为一个检查 点(checkpoint) 。在当前实现中,检查点只发生在 Namenode 启动时,在不久的将来将实现支持 周期性的检查点。


(2)Secondary NameNode详解

Secondary NameNode:并非 NameNode 的热备。当NameNode 挂掉的时候,它并不能马上替换 NameNode 并提供服务。


辅助 NameNode,分担其工作量。

定期合并 fsimage和fsedits,并推送给NameNode。

在紧急情况下,可辅助恢复NameNode。

3.jpeg


SecondaryNameNode会定期和NameNode通信,请求其停止使用EditLog文件,暂时将新的写操作写到一个新的文件edit.new上来,这个操作是瞬间完成,上层写日志的函数完全感觉不到差别;

SecondaryNameNode通过HTTP GET方式从NameNode上获取到FsImage和EditLog文件,并下载到本地的相应目录下;

SecondaryNameNode将下载下来的FsImage载入到内存,然后一条一条地执行EditLog文件中的各项更新操作,使得内存中的FsImage保持最新;这个过程就是EditLog和FsImage文件合并;

SecondaryNameNode执行完(3)操作之后,会通过post方式将新的FsImage文件发送到NameNode节点上

NameNode将从SecondaryNameNode接收到的新的FsImage替换旧的FsImage文件,同时将edit.new替换EditLog文件,通过这个过程EditLog就变小了


(3)HDFS NameSpace详解

HDFS 支持传统的层次型文件组织结构。用户或者应用程序可以创建目录,然后将文件保存在这些目录里。文件系统名字空间的层次结构和大多数 现有的文件系统类似:用户可以创建、删除、移动或重命名文件。当前, HDFS 不支持用户磁盘配额和访问权限控制,也不支持硬链接和软链接。但 是 HDFS 架构并不妨碍实现这些特性。

Namenode 负责维护文件系统命名空间,任何对文件系统名字空间或属 性的修改都将被 Namenode 记录下来。应用程序可以设置 HDFS 保存的文件 的副本数目。文件副本的数目称为文件的副本系数,这个信息也是由 Namenode 保存的。


(4)DataNode详解

DataNode:就是Slave。NameNode 下达命令,DataNode 执行实际的操作。


存储实际的数据块。

执行数据块的读/写操作。

Datanode 将 HDFS 数据以文件的形式存储在本地的文件系统中,它并不知道有 关 HDFS 文件的信息。它把每个 HDFS 数据块存储在本地文件系统的一个单独的文件 中。 Datanode 并不在同一个目录创建所有的文件,实际上,它用试探的方法来确定 每个目录的最佳文件数目,并且在适当的时候创建子目录。在同一个目录中创建所 有的本地文件并不是最优的选择,这是因为本地文件系统可能无法高效地在单个目 录中支持大量的文件。

当一个 Datanode 启动时,它会扫描本地文件系统,产生一个这些本地文件对应 的所有 HDFS 数据块的列表,然后作为报告发送到 Namenode ,这个报告就是块状态 报告。


(5)Client详解

Client:就是客户端。


文件切分。文件上传 HDFS 的时候,Client 将文件切分成 一个一个的Block,然后进行存储。

与 NameNode交互,获取文件的位置信息。

与 DataNode 交互,读取或者写入数据。

Client 提供一些命令来管理HDFS,比如启动或者关闭HDFS。

Client 可以通过一些命令来访问 HDFS。


(6)HDFS通信协议

所有的 HDFS 通讯协议都是构建在 TCP/IP 协议上。客户端通过一个可 配置的端口连接到 Namenode , 通过 ClientProtocol 与 Namenode 交互。而Datanode 是使用 DatanodeProtocol 与 Namenode 交互。再设计上,DataNode 通过周期性的向 NameNode 发送心跳和数据块来保持和 NameNode 的通信,数据块报告的信息包括数据块的属性,即数据块属于哪 个文件,数据块 ID ,修改时间等, NameNode 的 DataNode 和数据块的映射 关系就是通过系统启动时DataNode 的数据块报告建立的。从 ClientProtocol 和 Datanodeprotocol 抽象出一个远程调用 ( RPC ), 在设计上, Namenode 不会主动发起 RPC , 而是是响应来自客户端和 Datanode 的 RPC 请求。


(7)HDFS的安全模式

Namenode 启动后会进入一个称为安全模式的特殊状态。处于安全模式 的Namenode 是不会进行数据块的复制的。 Namenode 从所有的 Datanode 接收心跳信号和块状态报告。块状态报告包括了某个 Datanode 所有的数据 块列表。每个数据块都有一个指定的最小副本数。当 Namenode 检测确认某 个数据块的副本数目达到这个最小值,那么该数据块就会被认为是副本安全 (safely replicated) 的;在一定百分比(这个参数可配置)的数据块被 Namenode 检测确认是安全之后(加上一个额外的 30 秒等待时间), Namenode 将退出安全模式状态。接下来它会确定还有哪些数据块的副本没 有达到指定数目,并将这些数据块复制到其他 Datanode上。


三、HDFS文件读写的解析


(1)文件读取流程

4.jpeg

HDFS的文件读取原理,主要包括以下几个步骤:


首先调用FileSystem对象的open方法,其实获取的是一个DistributedFileSystem的实例。

DistributedFileSystem通过RPC(远程过程调用)获得文件的第一批block的locations,同一block按照重复数会返回多个locations,这些locations按照hadoop拓扑结构排序,距离客户端近的排在前面。

前两步会返回一个FSDataInputStream对象,该对象会被封装成DFSInputStream对象,DFSInputStream可以方便的管理datanode和namenode数据流。客户端调用read方法,DFSInputStream就会找出离客户端最近的datanode并连接datanode。

数据从datanode源源不断的流向客户端。

如果第一个block块的数据读完了,就会关闭指向第一个block块的datanode连接,接着读取下一个block块。这些操作对客户端来说是透明的,从客户端的角度来看只是读一个持续不断的流。

如果第一批block都读完了,DFSInputStream就会去namenode拿下一批blocks的location,然后继续读,如果所有的block块都读完,这时就会关闭掉所有的流。


(2)文件写入流程

5.jpeg

HDFS的文件写入原理,主要包括以下几个步骤:


客户端通过调用 DistributedFileSystem 的create方法,创建一个新的文件。

DistributedFileSystem 通过 RPC(远程过程调用)调用NameNode,去创建一个没有blocks关联的新文件。创建前,NameNode会做各种校验,比如文件是否存在,客户端有无权限去创建等。如果校验通过,NameNode 就会记录下新文件,否则就会抛出IO异常。

前两步结束后会返回 FSDataOutputStream 的对象,和读文件的时候相似,FSDataOutputStream 被封装DFSOutputStream,DFSOutputStream 可以协调 NameNode和DataNode。客户端开始写数据到DFSOutputStream,DFSOutputStream会把数据切成一个个小packet,然后排成队列data queue。

DataStreamer 会去处理接受 data queue,它先问询 NameNode 这个新的 block最适合存储的在哪几个DataNode里,比如重复数是3,那么就找到3个最适合的 DataNode,把它们排成一个pipeline。DataStreamer 把 packet 按队列输出到管道的第一个 DataNode 中,第一个DataNode又把 packet 输出到第二个 DataNode 中,以此类推。

DFSOutputStream 还有一个队列叫ack queue,也是由 packet组成,等待DataNode的收到响应,当pipeline中的所有DataNode都表示已经收到的时候,这时akcqueue才会把对应的packet包移除掉。 客户端完成写数据后,调用close方法关闭写入流。

DataStreamer把剩余的包都刷到 pipeline 里,然后等待 ack 信息,收到最后一个 ack 后,通知 DataNode 把文件标示为已完成。

流水线复制:

当客户端向 HDFS 文件写入数据的时候,一开始是写到本地临时文件中。假设该文件的副 本系数设置为 3 ,当本地临时文件累积到一个数据块的大小时,客户端会从 Namenode 获取一个 Datanode 列表用于存放副本。然后客户端开始向第一个 Datanode 传输数据,第一个 Datanode 一小部分一小部分 (4 KB) 地接收数据,将每一部分写入本地仓库,并同时传输该部分到列表中 第二个 Datanode节点。第二个 Datanode 也是这样,一小部分一小部分地接收数据,写入本地 仓库,并同时传给第三个 Datanode 。最后,第三个 Datanode 接收数据并存储在本地。因此, Datanode 能流水线式地从前一个节点接收数据,并在同时转发给下一个节点,数据以流水线的 方式从前一个 Datanode 复制到下一个


更细节的原理:

客户端创建文件的请求其实并没有立即发送给 Namenode ,事实上,在刚开始阶 段 HDFS 客户端会先将文件数据缓存到本地的一个临时文件。应用程序的写操作被透 明地重定向到这个临时文件。当这个临时文件累积的数据量超过一个数据块的大小 ,客户端才会联系 Namenode 。 Namenode 将文件名插入文件系统的层次结构中,并 且分配一个数据块给它。然后返回 Datanode 的标识符和目标数据块给客户端。接着 客户端将这块数据从本地临时文件上传到指定的 Datanode 上。当文件关闭时,在临 时文件中剩余的没有上传的数据也会传输到指定的 Datanode 上。然后客户端告诉 Namenode 文件已经关闭。此时 Namenode 才将文件创建操作提交到日志里进行存储 。如果 Namenode 在文件关闭前宕机了,则该文件将丢失。


四、副本机制


特点:


数据类型单一

副本数比较多

写文件时副本的放置方法

动态的副本创建策略

弱化的副本一致性要求

副本摆放策略:

6.jpeg

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
24天前
|
设计模式 安全 Java
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
27 0
|
1天前
|
存储 关系型数据库 分布式数据库
电子好书发您分享《PolarDB分布式版架构介绍PolarDB分布式版架构介绍》
**《PolarDB分布式版架构介绍》电子书分享:** 探索阿里云PolarDB分布式设计,采用计算存储分离,借助GMS、CN组件实现大规模扩展。[阅读更多](https://developer.aliyun.com/ebook/8332/116553?spm=a2c6h.26392459.ebook-detail.5.3b3b2ccbVVjjt0)
10 3
|
2天前
|
存储 关系型数据库 分布式数据库
电子好书发您分享《PolarDB分布式版架构介绍》
**探索PolarDB分布式版:阿里巴巴云的高扩展数据库解决方案,采用计算存储分离架构,确保高性能和弹性扩展。[阅读详情](https://developer.aliyun.com/ebook/8332/116553?spm=a2c6h.26392459.ebook-detail.5.33ac2ccbVd9TB2)**
90 7
|
24天前
|
存储 监控 安全
金石推荐 | 【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
金石推荐 | 【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
46 0
|
24天前
|
缓存 算法 关系型数据库
深度思考:雪花算法snowflake分布式id生成原理详解
雪花算法snowflake是一种优秀的分布式ID生成方案,其优点突出:它能生成全局唯一且递增的ID,确保了数据的一致性和准确性;同时,该算法灵活性强,可自定义各部分bit位,满足不同业务场景的需求;此外,雪花算法生成ID的速度快,效率高,能有效应对高并发场景,是分布式系统中不可或缺的组件。
深度思考:雪花算法snowflake分布式id生成原理详解
|
24天前
|
存储 Java 应用服务中间件
【分布式技术专题】「架构实践于案例分析」盘点互联网应用服务中常用分布式事务(刚性事务和柔性事务)的原理和方案
【分布式技术专题】「架构实践于案例分析」盘点互联网应用服务中常用分布式事务(刚性事务和柔性事务)的原理和方案
45 0
|
24天前
|
canal 消息中间件 关系型数据库
【分布式技术专题】「分布式技术架构」MySQL数据同步到Elasticsearch之N种方案解析,实现高效数据同步
【分布式技术专题】「分布式技术架构」MySQL数据同步到Elasticsearch之N种方案解析,实现高效数据同步
73 0
|
24天前
|
缓存 应用服务中间件 数据库
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(多级缓存设计分析)
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(多级缓存设计分析)
28 1
|
2天前
|
敏捷开发 监控 数据管理
构建高效微服务架构的五大关键策略
【4月更文挑战第20天】在当今软件开发领域,微服务架构已经成为一种流行的设计模式,它允许开发团队以灵活、可扩展的方式构建应用程序。本文将探讨构建高效微服务架构的五大关键策略,包括服务划分、通信机制、数据管理、安全性考虑以及监控与日志。这些策略对于确保系统的可靠性、可维护性和性能至关重要。
|
15天前
|
API 数据库 开发者
构建高效可靠的微服务架构:后端开发的新范式
【4月更文挑战第8天】 随着现代软件开发的复杂性日益增加,传统的单体应用架构面临着可扩展性、维护性和敏捷性的挑战。为了解决这些问题,微服务架构应运而生,并迅速成为后端开发领域的一股清流。本文将深入探讨微服务架构的设计原则、实施策略及其带来的优势与挑战,为后端开发者提供一种全新视角,以实现更加灵活、高效和稳定的系统构建。
18 0