大数据系列2:Hdfs的读写操作
在前文大数据系列1:一文初识Hdfs中,我们对Hdfs
有了简单的认识。
在本文中,我们将会简单的介绍一下Hdfs
文件的读写流程,为后续追踪读写流程的源码做准备。
Hdfs 架构
首先来个Hdfs
的架构图,图中中包含了Hdfs
的组成与一些操作。
对于一个客户端而言,对于Hdfs的操作不外乎也就读写两个操作,接下来就去看看整个流程是怎么走的。
下面我们由浅及深,氛围简单流程,详细流程分别介绍读写过程
简单流程
读请求流程
客户端需要读取数据的时候,流程大致如下:
Client
向NameNod
e发起读请求NameNode
收到读请求后,会返回元数据,包括请求文件的数据块在DataNode
的具体位置。Client
根据返回的元数据信息,找到对应的DataNode
发起读请求DataNode
收到读请求后,会返回对应的Block
数据给Client
。
写请求流程
客户端需要写入数据的时候,流程大致如下:
Client
向NameNode
发起写请求,其中包含写入的文件名,大小等。NameNode
接收到信息,NameNode
会将文件的信息存储到本地,同时判断客户端的权限、以及文件是否存在等信息,验证通过后NameNode
返回数据块可以存储的DataNode
信息。- 客户端会切割文件为多个
Block
,将每个Block
写入DataNode
,在DataNode
之间通过管道,对Block
做数据备份。
详细流程
读请求流程
客户端需要读取数据的时候,流程大致如下:
- 客户端通过调用
FileSystem
的open()
方法来读取文件。、 - 这个对象是
DistributedFileSystem
的一个实例,通过远程调用(RPC)与NameNode
沟通,会向NameNode
请求需要读写文件文件的Block
位置信息。 NameNode
会进行合法性校验,然后返回Block
位置信息,每一个Block
都回返回存有该副本的DataNode
地址,并且会根据DtaNode与Client的距离进行排序(这里的距离是指集群网络拓扑的距离,也是尽可能满足数据本地性的要求)DistributedFileSystem
会返回一个支持文件定位的输入流FSDataInputStream
给客户端,其中封装着DFSInputStream
对象,该对象管理者DataNode
和NameNode
之间的I/O
Client
对这个输入流调用read()
方法DFSInputStream
存储了文件中前几个块的DataNode
地址,然后在文件第一个Block
所在的DataNode
中连接最近的一个DtaNode
。通过对数据流反复调用read()
,可以将数据传输到客户端。- 当到到
Block
的终点的时候,DFSInputStream
会关闭与DataNode
的链接。然后搜寻下一个Block
的DataNode
重复6、7步骤。在Client
看来,整个过程就是一个连续读取过程。 - 当完成所有
Block
的读取后,Client
会对FSDataInputStream
调用close()
Client
读取数据流的时候,Block
是按照DFSInputStream
与DataNode
打开新的连接的顺序读取的。
并且在有需要的时候,还会请求NameNode
返回下一个批次Blocks
的DataNode
信息
在DFSInputStream
与DataNode
交互的时候出现错误,它会尝试选择这个Block
另一个最近的DataNode
,并且标记之前的DataNode
避免后续的Block
继续在该DataNode
上面出错。
DFSInputStream
也会对来自DataNode
数据进行校验,一旦发现校验错误,也会从其他DataNode
读取该Bclock
的副本,并且向NamaNode
上报Block
错误信息。
整个流程下来,我们可以发现Client直接连接到DataNode检索数据并且通过NameNode知道每个Block的最佳DataNode。
这样设计有一个好处就是:
因为数据流量分布在集群中的所有DataNode
上,所以允许Hdfs扩展到大量并发Client.
与此同时,NamaNode
只需要响应Block
的位置请求(这些请求存储在内存中,非常高效),
而不需要提供数据。
否则随着客户端数量的快速增加,NameNode会成为成为性能的瓶颈。
读请求流程
客户端需要写入数据的时候,流程大致如下:
Client
通过create()
方法调用DistributedFileSystem
的create()
DistributedFileSystem
通过RPC
向NameNode
请求建立在文件系统的明明空间中新建一个文件,此时只是建立了一个空的文件加,并没有Block
。NameNode
接收到crete
请求后,会进行合法性校验,比如是否已存在想通文件,Client
是否有相关权限。如果校验通过,NameNode
会为新文件创建一个记录,并返回一些可用的DataNode
。否则客户端抛出一个IOException
DistributedFileSystem
会返回一个FSDataOutputStream个Client
,与读取数据类似,FSDataOutputStream
封装了一个DFSOutputStream
,负责NameNode
与DataNode
之间交互。Client
调用write()
DFSOutputStream
会将数据切分为一个一个packets
,并且将之放入一个内部队列(data queue
),这个队列会被DataStreamer
消费,DataStreamer
通过选择一组合合适DataNodes
来写入副本,并请求NameNode
分配新的数据块。与此同时,DFSOutputStream
还维护一个等待DataNode
确认的内部包队列(ack queue
)- 这些
DataNodes
会被组成一个管道(假设备份数量为3
) - 一旦
pipeline
建立,DataStreamer
将data queue
中存储的packet
流式传入管道的第一个DataNode
,第一个DataNode存储Packet并将之转发到管道中的第二个DataNode
,同理,从第二个DataNode
转发到管道中的第三个DataNode
。 - 当所一个
packet
已经被管道中所有的DataNode
确认后,该packet
会从ack queue
移除。 - 当
Client
完成数据写入,调用close()
,此操作将所有剩余的数据包刷新到DataNode
管道,等待NameNode
返回文件写入完成的确认信息。 NameNode
已经知道文件是由哪个块组成的(因为是DataStreamer
请求NameNode
分配Block
的),因此,它只需要等待Block
被最小限度地复制,最后返回成功。
如果在写入的过程中国发生了错误,会采取以下的操作:
- 关闭管道,并将所有在
ack queue
中的packets
加到data queue
的前面,避免故障节点下游的DataNode
发生数据丢失。 - 给该
Block
正常DataNode
一个新的标记,将之告知NameNode
,以便后续故障节点在恢复后能删除已写入的部分数据。 - 将故障节点从管道中移除,剩下的两个正常
DataNodes
重新组成管道,剩余的数据写入正常的DataNodes
。 - 当
NameNode
发现备份不够的时候,它会在另一个DataNode
上创建一个副本补全,随后该Blcok
将被视为正常
针对多个DataNode
出现故障的情况,我们只要设置 dfs.NameNode.replication.min
的副本数(默认为1),Block
将跨集群异步复制,直到达到其目标复制因子( dfs.replication
,默认为3)为止.
通俗易懂的理解
上面的读写过程可以做一个类比,
NameNode
可以看做是一个仓库管理员;
DataNode
可以看作是仓库;
管理员负责管理商品,记录每个商品所在的仓库;
仓库负责存储商品,同时定期想管理员上报自己仓库中存储的商品;
此处的商品可以粗略的理解为我们的数据。
管理员只能有一个,而仓库可以有多个。
当我们需要出库的时候,得先去找管理员,在管理员处取得商品所在仓库的信息;
我们拿着这个信息到对应仓库提取我们需要的货物。
当我们需要入库的时候,也需要找管理员,核对权限后告诉我们那些仓库可以存储;
我们根据管理员提供的仓库信息,将商品入库到对应的仓库。
存在的问题
上面是关于Hdfs
读写流程介绍,虽然我分了简单和详细,但是实际的读写比这个过程复杂得多。
比如如何切块?
为何小于块大小的文件按照实际大小存储?
备份是如何实现的?
Block
的结构等等。
这些内容会在后续的源码部分详细解答。
此外,有人也许发现了,前文大数据系列1:一文初识Hdfs中Hdfs架构的介绍和本文读写的流程的介绍中,存在一个问题。
就是NameNode
的单点故障问题。虽然之前有SecondaryNameNode
辅助NameNode
合并fsiamge
和edits
,但是这个还是无法解决NameNode
单点故障的问题。
很多人听过HA(High Availability)
即高可用,误以为高可用就是SecondaryNameNode
,其实并不是。
在下一篇文章中会介绍Hdfs
高可用的实现方式。
想了解更多内容观影关注:【兔八哥杂谈】
大数据系列2:Hdfs的读写操作的更多相关文章
- 大数据学习之HDFS基本API操作(下)06
hdfs文件流操作方法一: package it.dawn.HDFSPra; import java.io.BufferedReader; import java.io.FileInputStream ...
- 【大数据系列】Hadoop DataNode读写流程
DataNode的写操作流程 DataNode的写操作流程可以分为两部分,第一部分是写操作之前的准备工作,包括与NameNode的通信等:第二部分是真正的写操作. 一.准备工作 1.首先,HDFS c ...
- 【大数据系列】HDFS初识
一.HDFS介绍 HDFS为了做到可靠性(reliability)创建了多分数据块(data blocks)的复制(replicas),并将它们放置在服务集群的计算节点中(compute nodes) ...
- 大数据学习之HDFS基本API操作(上)06
package it.dawn.HDFSPra; import java.io.FileNotFoundException; import java.io.IOException; import ja ...
- 【大数据系列】HDFS安全模式
一.什么是安全模式 安全模式时HDFS所处的一种特殊状态,在这种状态下,文件系统只接受读数据请求,而不接受删除.修改等变更请求.在NameNode主节点启动时,HDFS首先进入安全模式,DataNod ...
- 【大数据系列】HDFS文件权限和安全模式、安装
HDFS文件权限 1.与linux文件权限类型 r:read w:write x:execute权限x对于文件忽略,对于文件夹表示是否允许访问其内容 2.如果linux系统用户sanglp使用hado ...
- 大数据系列之并行计算引擎Spark介绍
相关博文:大数据系列之并行计算引擎Spark部署及应用 Spark: Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎. Spark是UC Berkeley AMP lab ( ...
- 大数据系列4:Yarn以及MapReduce 2
系列文章: 大数据系列:一文初识Hdfs 大数据系列2:Hdfs的读写操作 大数据谢列3:Hdfs的HA实现 通过前文,我们对Hdfs的已经有了一定的了解,本文将继续之前的内容,介绍Yarn与Yarn ...
- 大数据系列(3)——Hadoop集群完全分布式坏境搭建
前言 上一篇我们讲解了Hadoop单节点的安装,并且已经通过VMware安装了一台CentOS 6.8的Linux系统,咱们本篇的目标就是要配置一个真正的完全分布式的Hadoop集群,闲言少叙,进入本 ...
随机推荐
- angular8 大地老师学习笔记---第六课
export class TodolistComponent implements OnInit { public keyword:string; public todolist:any[]=[]; ...
- 前端Firebug常见错误:SyntaxError:missing variable nam
出现上面那个问题应该是 某个地方,分号写错了 检查一下是否由于应该写分号的地方写成了其他符号.
- robotframework中的参数展开
robot调用关键字传参的方式是用分隔符分开不同参数,如 keyword arg1 arg2 arg3 arg4 当参数中传入了使用@符号的列表变量时,@符号会将列表展开: @{list1}= Cre ...
- 华为全栈AI技术干货深度解析,解锁企业AI开发“秘籍”
摘要:针对企业AI开发应用中面临的痛点和难点,为大家带来从实践出发帮助企业构建成熟高效的AI开发流程解决方案. 在数字化转型浪潮席卷全球的今天,AI技术已经成为行业公认的升级重点,正在越来越多的领域为 ...
- TypeError: filter() got an unexpected keyword argument 'XXX'
Flask使用SQLAlchemy查询报如下错误: TypeError: filter() got an unexpected keyword argument 'XXX' 出错原因: 查询错误,应该 ...
- 【JAVA并发第二篇】Java线程的创建与运行,线程状态与常用方法
1.线程的创建与运行 (1).继承或直接使用Thread类 继承Thread类创建线程: /** * 主类 */ public class ThreadTest { public static voi ...
- Dubbo SPI源码解析①
目录 0.Java SPI示例 1.Dubbo SPI示例 2.Dubbo SPI源码分析 SPI英文全称为Service Provider Interface.它的作用就是将接口实现类的全限定名 ...
- 《深入理解Java虚拟机》 Java对象的生命周期
Java虚拟机运行时数据区 方法区:存储 类信息.常量.静态变量.即使编译器编译后的代码等数据,也有别名叫做非堆. 方法区其中有包含有 运行时常量池,用于存放编译期生成的各种字面量和符号引用.其中, ...
- 基于腾讯云存储COS的ClickHouse数据冷热分层方案
一.ClickHouse简介 ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS),支持PB级数据量的交互式分析,ClickHouse最初是为YandexMetrica ...
- 一网打尽,一文讲通虚拟机VirtualBox及Linux使用
本文将从虚拟机的选择.安装.Linux系统安装.SSH客户端工具使用四个方面来详细介绍Linux系统在虚拟机下的安装及使用方法,为你在虚拟机下正常使用Linux保驾护航. 1.虚拟机的选择 在讲虚拟机 ...