文件的写入过程
这里的FSDatainputStream改成outputstream
第一步:客户client 发送文件上传的请求给NameNode,NameNode去检查目标文件是否存在,父目录是否存在,返回是否上传
第二步:接受指令 , 给NameNode发送Block1可以传输到datanode的那些服务器上
第三步:NameNode根据当前配置和机架感知原理来进行分配,如返回datanode的地址:A1 A6 B6
第四步:client客户请求三台中其中一台A1上传数据(本质上是一个RPC的一个调用,建立pipeline) ,A1收到请求会调用A6 ,A6会传给 B6 ,将整个pipeline建立完成,后逐级返回给client
第五步:client客户开始上传第一个Block到A1,执行流水线复制,以packet为单位(默认64k) ,A1收到第一个block会传给A6 ,A6传给B6 ,A每传一个packet会放入一个应答队列等待应答
第六步:数据被分割成一个个packet在pipeline上依次传输,在pipeline的反方向上,逐个发送ack,最后由pipeline中的第一个datanode中的A1把数据包发送个client客户
第七步:关闭写入流
第八步:当第一个block写完之后,客户请求namenode 上传第二个block到服务器上,逐步循环下去
文件的读取过程
第一步:client客户端调用filestream的Open方法来读取希望打开的文件
第二步:client客户端向namenode发送请求,来确定block文件所在的位置
第三步:namenode返回该文件所在所有的block的所有的datanode信息(namenode会返回有该块副本的datanode的信息,并按照距离对datanode进行排序)
第四步:client选取排序靠前的的datanode来读取block,如果客户端就是datanode就调用本地直接获取
第五步:重复调用父类read()方法,直到把block读取完为止
第六步:并行读取,读取失败就重新读取
第七步: 当读完第一个 block 后,若文件读取还没有结束,客户端会继续向NameNode 获取下一批的 block 列表; 第八步:返回后续block列表
第九步:最终关流,把读取好的所有block合成一个完整的文件