HDFS的写入流程:
* 1-
客户端向
NameNode
发起写入数据的请求
, NameNode
接收到写入请求后
,
首先会判断对应目录下是否存在要写入的文件,
如果有立即报错
,
说写入的文件以存在
,
如果不存在
,
还会校验是否有写入数据权限
,
如果没有
,
直接报错
,
报权限不足,
如果既不存在
,
也有权限
,
就会给客户端返回可以写入
* 2-
客户端开始对要写入的文件进行切割操作
,
默认是按照
128M
一个快来进行切割
,
切割完后
,
拿着第一个
Block
块再次请求NameNode,
询问应该放置到那个位置下
* 3- NameNode
接收到请求后
,
会根据负载均衡、机架感知原理、副本机制从所有的
DataNode
选择一些合适的
DataNode
的节点地址返回给客户端
* 4- 客户端
接收到
NameNode
返回的
DataNode
节点列表后
,
首先会先连接列表中第一个
DataNode,
然后让第一个DataNode连接第二次
,
第二个连接第三次
,
以此类推
,
形成一个数据传输管道
,
同时反向还会构建一条
ACK
确认管道
* 5-
客户端开始进行写入数据
,
数据通过数据包的形式来进行传输
,
每一个数据包为
64kb
大小
,
当第一个
DataNode
接收到数据后,
然后传递给第二个
,
第二个传递给第三个 完成数据保存同时每个节点接收到
,
还是在
ACK
中进行确认操作
* 6-
当客户端发现各个节点都收到消息后
,
开始传入下一个数据包
,
依次类推
,
知道将这个
block
所有的数据全部写完
* 7-
接着会拿着第二次
block
再次请求
NameNode,
询问
,
第二个
block
块应该存储在那些位置中
,
后续循环执行
3~7
直到将所有
block
全部都写完
读取流程:

* 1-
客户端向
NameNode
发起读取数据的请求
, NameNode
接收到读取数据请求后
,
首先判断对应目录下是否有这个数据
,
如果没有
,
直接报错
,
返回不存在此文件
,
如果有
,
接着判断是否有读取数据的权限
,
如果没有
,
直接报错
,
如果有
,
那
么就直接根据网络拓扑关系
,
机架感知原理 返回对应文件各个
block
所在的
DataNode
的地址
,
如果
block
比较多
,
可能
此时先返回一部分
,
如果块比较少
,
那么直接全部都返回了
* 2-
客户端
,
根据返回地址
,
可以选择并行的方式
,
或者串行的方式连接各个
DataNode
开始读取数据
,
采用
IO
流的方
式
,
直接获取
* 3-
如果
nameNode
仅返回了一部分
,
那么客户端会再次请求
Namenode
获取下一批
block
所在的地址
,
然后重复第二步
,
不断的将数据全部读取到本地
* 4-
当客户端全部读取完成后
,
将各个
block
按照顺序拼接在一起
,
形成了最终的文件