1.hdfs 写流程
对用户是无感知
1.1 hdfs client调用FileSystem.create(filePath)方法,去和NN进行【RPC】通信。
NN会去检查这个文件是否已经存在、是否有权限创建这个文件等一系列校验操作;
如果校验通过,就创建一个新的文件,但是这个没有数据,不关联任何的block的。
NN会根据文件的大小,再根据当前集群的块大小 128、副本数3,和当前的DN节点情况,
计算出这个文件要上传多少个块(包含副本)和块上传到哪些DN节点。
最终把这个信息返回给客户端【FsDataOutputStream】对象。
1.2 Client 调用【FsDataOutputStream】对象的write方法,
根据【副本放置策略】,将第一个块的本身写到DN1,写完复制到DN2,再写完复制到DN3.
当三个副本写完的时候,就返回一个ack package确认包给DN2,DN2接收到确认包加上自己也写完了,
给DN1发送ack package确认包加上DN1自己写完了,就给【FsDataOutputStream】,告诉它第一个块 三个副本都写完了。
以此类推。
1.3 当所有的块全部写完,Client调用【FsDataOutputStream】对象的close方法,关闭输出流。
再次调用FileSystem.complete方法,告诉NN文件写成功。
2.hdfs 读流程
2.1 Client调用FileSystem的open(filePath),与NN进行【RPC】通信。
返回这个文件的部分或者全部的block列表,
也就是返回【FSDataInputStram】对象。
2.2 Client调用【FSDataInputStram】对象的read方法,
去与第一个块的最近的DN的进行读取,读取完成后会校验,假如ok就关闭与DN通信。
假如不ok,就记录块和DN的信息,下次就不从这个节点读取,那么从第二个节点读取。
然后与第二个块的最近的DN进行读取,以此类推。
假如当block的列表全部读取完成,文件还没结束,再去NN请求下一个批次的block列表。
block1-1 dn1
block1-2 dn2
block1-3 dn3
block2-1 dn3
block2-2 dn1
block2-3 dn2
1.3 Client调用【FSDataInputStram】对象的close方法,关闭输入流。