1、HDFS写数据(宏观):
1、首先,客户端发送一个写数据的请求,通过rpc与NN建立连接,NN会做一些简单的校验,文件是否存在,是否有空间存储数据等。
2、NN就会将校验的结果发送给客户端,客户端就会向NN发送请求,第一个block存储在哪个DN中。
3、NN接受客户端请求,就会根据block块以及副本的数量来分配DN,并将对应的DN的地址返回给客户端。
4、客户端会向第一个DN发送请求,上传数据,第一个DN接受到以后就会向下一个DN发送请求,直到最后一个DN,将整个pipline管道创建成功,在返回给客户端。
5、此时客户端会将block切分成多个package,以package的形式传递到DN中,在pipiline中依次传输,当传输到最后一个DN的时候,就会返回一个ack响应,当客户端接收到最后一个DN传输过来的ack,此时package就传输完成,然后一次传输package。
6、当第一个block传输完成以后,客户端就会请求NN上传第二个block。
7、当所有的package传输完成后,管道就会关闭,数据传输成功。
2、HDFS写数据请求(微观:保证了在传输的过程中package不会发生错误):
1、首先,客户端发送写数据的请求,将磁盘中的数据从内存中提取出来,存放在客户端的内存中。
2、当客户端与NN之间通过rpc建立联系后,获取到第一个block存在的DN的地址,然后向第一个DN中发送写数据的请求,第一个DN接收到后调用下一个DN,以此类推,在所有的DN之间建立pipline管道。
3、当pipline管道建立后,客户端此时对每一个block在进行切分,分成多个package。
4、在客户端,为了防止在传输过程package不会出错,就会产生了两个两个队列,分别是数据队列(dataqueue)和确认队列(Ackqueue)。
5、此时会将缓存中的package读取到数据队列,同时也会复制一份到确认队列中
6、然后数据队列就会上传数据,然后通过Pipline管道分别就是package依次发送到对应的dn中
7、当客户端发送第一个package的时候,会有一个进程responseprosessor进程用来接收DN传来的ack的响应,如果接受到的ack是true,说明这个package传输成功,此时ackqueue中的package就会删除,反之ackqueue会将package复制一份给dataqueue重新发送,一直到收到的ack的状态时true。
3、HDFS的读数据请求:
1、客户端通过rpc与NN建立连接,发送读数据的请求
2、NN根据客户端的请求,NN将block以及对应副本所对应的DN的地址返回返回个客户端。
3、客户端会根据返回来的DN地址,会根据网络拓扑结构计算出与客户端的距离,然后进行排序。
4、客户端会选择距离较近的DN中去读取block,如果客户端就在DN中,就会在自生读取block,当block读取完成后,文件读取还没有结束,此时客户段会向NN继续发送读数据的请求,获取下一批的block的地址。
5、最终客户端会将这些读取的block合并成一个文件。
4、package的结构:
1、package主要分成两个部分:package header 和package data
一般的大小是64kb
haeder中存放的是:offset in block (在block中的偏移量),last packet in block (是不是block中的最后一个packet)
packdata中存放的是:chunk data (存储的数据),chunk checksum(校验文件,与chunkdata是一一对应的)