HDFS写数据:
客户端(rpc调用)链接上namenode
客户端有一个文件aaa.avi,要上传:
1、先要向namenode请求上传文件(namenode要先查看自己的内部账本,(哪个目录下面有什么文件)这个账本就是元数据(相当于数据库),看看是否有这个 aaa.avi,如果没有就返回namenode给客户端,说你可以上传。
2、客户端要再发一次请求,调用元数据上面的方法(函数),说客户端要上传一个block这个block是aaa.avi的部分文件,请namenode分客户端几个datanode, namenode返回客户端几个datanode。
3、namenode给客户端返回几个datanode(datanode列表dn1.dn2.dn3.dn4)考虑的因素有:空间和距离(数据到datanode的跳转)第一次选择datanode的选择会选择和 客户端最近的,第二个会选择跨机架的datanode,因为安全,增加可靠性,第三个会在第一个副本同一个机架上;还有个机架感知有兴趣可以看看。返回datanode的 数量是和客户端的block有关。
4、开始传数据,传之前,客户端需要首先建一个和dn1的流(为了和目标机器建立一个socket通道)然后客户端从这个socket通道里面拿到一个流,客户端将本地这个 文件流,往与dn1的通道里面去写。(先向dn1发送rpc请求。nio)建立请求传输通道nio,给dn1传的时候,dn1会告诉dn2,dn3,dn4,让后面的几个准备接受数 据,然后dn4,dn3,dn2响应前面的datanode,后面几个dn都没问题之后,dn1在应答客户端。
5、开始传输数据,用户先读取数据,把数据从文件channel(客户端内部实现的),读取到socketchannel中(客户端与dn1的链接的channel),然后再写入dn1,(刚 开始是小数据包packat,64k,然后dn1要先校验,然后在写)写完一个packat之后,交给通道,通道交给dn2,或者dn3用byteBuf存储,大小够了64k之后,再往 dn2,3,4开始写,这样副本就有了。(packat里面有一个trunk,上传以packat为单位,检验以trunk为单位,一个trank512个字节)
6、一个block传完以后,客户端会再向namenode去申请datanode,重复上面的1-4步骤。)