HDFS的工作机制
(1)HDFS写数据
客户端要向HDFS写数据,首先要跟NameNode通信以确认可以写文件并获得接收文件Block的DataNode,然后客户端按顺序将文件逐个Block传递给相应DataNode,并由接收到Block的DataNode负责向其他DataNode复制Block的副本
(1)HDFS客户端向NameNode发送上传文件的请求
(2)NameNode检查上传文件和目录,判断能否上传
(3)NameNode向HDFS客户端返回检查结果
(4)客户端得到上传允许,读取客户端配置
(5)客户端向NameNode请求上传数据块Block
(6)NameNode会根据客户端的配置来查询DataNode信息
(7)NameNode返回可用的DataNode服务器
注:使用默认配置,会返回同一个机架的两个datanode和另一个机架的datanode(机架感知)
(8)客户端向DataNode请求建立Block的传输通道PipeLine(实质上是RPC调用)
(9)DataNode收到请求后,会调用另外一个DataNode,直至将整个PipeLine建立
(10)客户端向第一个DataNode发送第一个Block(以Packet为单位)
(11)DataNode收到Packet后会发送给下一个DataNode,直至最后一个DataNode
注:客户端在开始传输Block之前会把数据缓存在本地,当缓存大小超过了一个Block的大小,客户端就会从NameNode获取要上传的DataNode列表
(12)DataNode每发送一个Packet会放入一个应答队列等待应答
(13)第一个Block传输完成后会使用同样的方式传输下面的Block直到整个文件上传完成
(14)客户端向NameNode汇报Block的传输结果
(15)NameNode更新元数据信息记录操作日志
注意:
- 请求和应答是使用RPC的方式。NameNode响应来自客户端或 datanode 的RPC请求。客户端和datanode之间是使用socket进行数据传输,和namenode之间的交互采用nio封装的RPC
- HDFS有自己的序列化协议
- 在Block传输成功后但客户端没有告诉NameNode之前如果NameNode宕机那么这个Block就会丢失
- 在流式复制时,逐级传输和响应采用响应队列来等待传输结果。队列响应完成后返回给客户端
- 在流式复制时如果有一台或两台(不是全部)没有复制成功,不影响最后结果,只不过DataNode会定期向NameNode汇报自身信息。如果发现异常NameNode会指挥DataNode删除残余数据和完善副本。如果副本数量少于某个最小值就会进入安全模式
(2)HDFS读数据
客户端将要读取的文件路径发送给NameNode,NameNode获取文件的元信息(主要是Block的存放位置信息)返回给客户端,客户端根据返回的信息找到相应DataNode逐个获取文件的Block并在客户端本地进行数据追加合并从而获得整个文件
(1)HDFS客户端向NameNode发起RPC通信,请求读取文件数据
(2)NameNode检查文件是否存在,获取目标文件的元信息
(3)客户端接收到元信息后选取网络距离最近的DataNode发送请求建立Socket流,依次读取每个Block
(4)客户端校检文件是否损坏,如果损坏,客户端会选取另外的datanode请求
(5)DataNode将对应的Block传输给客户端
(6)客户端接收到数据缓存到本地,之后写入文件
(7)DataNode传输剩下的Block,直到整个文件合并完成
参考资料:http://hadoop.apache.org/docs/stable2/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html