HDFS文件上传流程
-
客户端向NameNode发送数据上传请求,这个请求当中包含一个重要的信息就是文件的长度信息。假设该文件的大小为207M.
hadoop fs -put /test.txt /data
-
NameNode接收到客户端的请求之后会做一系列的检查
- 文件是否存在,如果存在,报错
- 上传文件的父目录是否存在,如果存在,报错
- 权限等其他内容检查
-
NameNode在检查通过之后会向客户端返回存储节点信息,返回节点的原则如下:
- 优先返回客户端所在节点
- 然后返回同客户端相同机架的节点
- 再返回不同机架的节点
这里假设返回给test.txt文件的块编号为blk_1,blk_2,并且
blk_1所有副本对应的节点是hadoop01,hadoop02,hadoop03
blk_2所有副本对应的节点是hadoop01,hadoop02,hadoop04
-
客户端接收到NameNode返回的响应之后,会先对数据进行逻辑切片。即,
blk_1 存储前128M的数据, 0-127
blk_2 存储剩余的数据, 128-206
-
开始准备上传文件,构建上传通道pipeline。存储同一个块的所有节点构建一个数据流通道。
即blk_1 对应一个通道,blk_2 对应一个通道。
-
开始真正上传文件,上传时以package为单位进行上传,并且在上传的过程中对文件进行物理切片。对于第一个块,上传的时候会先上传到hadoop01,上传到hadoop01时会先写到缓存中,缓存中每接收到一个package的数据就会向下传递,同时缓存中的数据会持续写到磁盘中。
-
当第一个块的数据上传完成。即,hadoop01,hadoop02,hadoop03三个节点都上传完毕之后,上传通道关闭。
-
开始上传第二个块,重复5,6,7步。
-
所有数据上传成功后,会向客户端返回上传结果。
-
客户端向NameNode返回信息,告知数据上传成功
上传过程中的异常
文件上传过程中,如果有一个节点上传失败,怎么办?hdfs会立即进行一次重试,如果还失败,会将失败的节点从pipeline中剔除,并将失败的节点报告给NameNode。
比如原始的pipeline是:hadoop01--hadoop02--hadoop04,假如hadoop02节点上传失败,那么会将hadoop02节点剔除,上传通道就变成hadoop01-hadoop04。
hdfs最大的忍受度为至少有一个节点上传成功,如果所有节点都上传失败,那么这个时候NameNode会重新申请节点,重新构建pipeline。