1.拥有HDFS的Client给NameNode发送RPC请求
2.NameNode收到请求会去判断请求中的文件夹是否存在,创建者是否有权限操作,如果判断成功则为文件创建一条记录,如果没有则抛出异常
3.当客户端写入数据时,开发库会将文件切割成过个数据包,以data queue 方式管理这些数据包 并向NameNode申请blocks,获取用来储存这个replicas(备份)的DataNode,但是具体是多少需要看NameNode对replication的设置。
4.然后开始以管道的形式将数据写入到所有的备份中,开发库把数据已流的方式写入到第一个DataNode,该DataNode写完数据后会将刚才管道中的数据传递给一个需要储存的DataNode,而不是客户端在单独发送给下一个DataNode,这样做个人感觉有两大好处,第一:节省时间,因为假如我需要将数据放到3个DataNode,如果客户端向每个DataNode都发送一遍请求 那么客户端将执行三次写入操作,如果我只发给1个DataNode 然后在 第一个DataNode执行完时直接进行反馈告诉客户端我执行完毕,后面的2个DataNode在后台慢慢的存,这样客户端那面就会感觉很快,第二DataNode之间的传输速度怎么也比客户端直接传输速度只高不低
5.如果在传输过程中某个DataNode出现了故障,这时也不用担心,它会将当前的管道关闭,然后将这个坏掉的DataNode在管道中移除剩下 blocks将会继续在 剩下的DataNodes 进行传输 出现故障的DataNode ,NameNode会重新分配一个新的DataNode,来保证replicas设置的数量
6.当最后一个DataNode接收完数据后,返回一个ack packet,在pipeline里传递至客户端,在客户端的开发库内部维护着"ack queue",成功收到datanode返回的ack packet后会从"ack queue"移除相应的packet。