HDFS 上传文件和读文件的流程

(1)由客户端 Client 向 NameNode 节点发出请求;
(2)NameNode 向 Client 返回可以存数据的 DataNode 列表,这里遵循机架感应原则(把副本分别放在不同的机架,甚至不同的数据中心);
(3)客户端首先根据返回的信息先将文件分块(Hadoop2.X 版本每一个 block 为128M,而之前的版本为 64M); 

(4)通过 NameNode 返回的 DataNode 信息,将文件块以写入方式直接发送给DataNode,同时复制到其他两台机器(默认一份数据,有两个副本);
(5)数据块传送完成以后,dataNode 向 Client 通信,同时向 NameNode 报告;
(6)依照上面(4)到(5)的原理将所有的数据块都上传,结束后向 NameNode 报告表明已经传完所有的数据块。

  • Hadoop1版本
  • 客户端依据最近空闲原则选择一个节点,在不同机架上选择第二个副本节点,在第二个节点的同机架下选择第三个节点
  • Hadoop2版本
  • 客户端依据最近空闲选择一个节点,在当前节点同机架下选择第二个副本节点,在不同机架上选择第三个节点

 

一、HDFS写流程:

(1)客户端通过Distributed FileSystem模块向NameNode请求上传文件,NameNode检查目标文件是否已存在,父目录是否存在,检查客户端是否有权限,如果以上条件均满足,执行(2)
(2)NameNode响应客户端的请求,允许其上传文件。
(3)客户端请求第一个 Block上传到哪几个DataNode服务器上。
(注意:NameNode在返回3个DataNode节点之前,会存储相关信息到元数据,用于对其的管理)
(4)NameNode返回3个DataNode节点,分别为dn1、dn2、dn3。
(注意:这里是根据网络拓扑计算节点的距离,按照最近距离进行分配。一般而言,再本机机架节点负载允许的范围内,会优先选择本机机架节点当作dn1,然后选择最近的机架。用改机架的两个服务端当作其余两个节点dn1,dn2)
(5)客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成。
(注意:这里的通信信道建立属于类似“串联”的方式进行连接。是由客户端根据NameNode的返回信息,找到dn1,然后,dn1找dn2,dn2找dn3)
(6)dn1、dn2、dn3逐级应答客户端。
(7)客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答。
(注意:此处再传送packet时,会再建立一个队列,用于暂存还未存储的packet,当packet请求存储成功后,会从队列中删除,这样做的目的是,防止传输时,packet因为请求延迟等原因,导致信息丢失)
(8)当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。(重复执行3-7步)。
二、 HDFS读数据流程

(1)客户端通过DistributedFileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。
(2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。
(3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。
(4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。

NameNode 在启动的时候会做哪些操作

 

NameNode 启动的时候,会加载 fsimage
Fsimage 加载过程完成的操作主要是为了:
(1)从 fsimage 中读取该 HDFS 中保存的每一个目录和每一个文件
(2)初始化每个目录和文件的元数据信息
(3)根据目录和文件的路径,构造出整个 namespace 在内存中的镜像
(4)如果是文件,则读取出该文件包含的所有 blockid,并插入到 BlocksMap 中。

 

 

Hadoop怎么分片

 

HDFS 存储系统中,引入了文件系统的分块概念(block),

块是存储的最小单位,HDFS定义其大小为 64MB。

与单磁盘文件系统相似,存储在 HDFS 上的文件均存储为多个块,不同的是,如果某文件大小没有到达 64MB,该文件也不会占据整个块空间。

在分布式的 HDFS集群上,Hadoop 系统 保证一个块存储在一个 datanode 上。

HDFS 的 namenode 只存储整个文件系统的元数据镜像,这个镜像由配置 dfs.name.dir指定,

datanode 则存有文件的 metainfo 和具体的分块,存储路径由 dfs.data.dir 指定。