参考文献:https://blog.csdn.net/b6ecl1k7BS8O/article/details/88386764
一,写入流程:
-
1,客户端向nn发送创建文件的请求
-
2,nn检查目录是否存在、文件是否存在。目录存在、文件不存在,则允许上传文件
-
3,客户端根据集群配置切分文件,默认是一个block 128m
-
4,客户端向nn请求上传第一个block,nn生成block id,从集群中选择三个节点(假设集群配置了3个副本)
-
5,客户端选取了一个最近的datanode,发起上传block1的请求,dn1接收到请求后,将请求转发给dn2,dn2将请求转发给dn3,dn3接收到请求后确认,响应给dn2,dn2响应给
dn1,dn1响应给客户端,这样就建立了传输数据的pipeline -
6,客户端以packet为单位向dn发送数据,packet大小可配置,默认是64k。客户端以chunk为单位写数据,chunk有4个字节记录这个chunk存储的数据的校验和。chunk写满后,塞入packet,packet被塞满后,才会发送给dn,packet被data queue管理。packet被发送后,从data queue 移除,转移到ack queue中。packet先被发送到dn1,dn1发送给dn2,dn2发送给dn3。dn3写入成功后响应ack 给dn2,dn2响应ack给dn1,dn1响应给客户端。客户端收到响应后,从ack queue中移除当前packet。
-
7,block数据全部发送后,datanode向nn报告,nn保存文件与block的信息及block的地址信息。
-
8,第二个block重复以上步骤。
二,容错:
1,某个packet出错,客户端收不到该packet的响应,会将packet从ack queue重新附加到data queue的尾部,等待重传。
2,某个datanode宕机,客户端会将ack queue中的packet全部转移到data queue,这部分packet没有得到写入成功的响应,且dn已经宕机,后续不能接收到写入成功的响应。将宕机的dn从pipeline移除,重新向nn申请一台dn,将新dn加入pipeline,pipeline中的其他dn将已经写入成功的packet copy到新的dn。
三,写入的节点选择
第一种算法
- 1,查看客户端位置,如果在集群中就选择所在节点,若不在就随机算则一个集群中的节点dn1。
- 2,第二个副本的位置就是在集群中的除了dn1的节点随机选择一个dn2.
- 3,第三个就要选择dn2所在的机架,节点随机选择dn3
这三个节点有可能在一个机架,取决于第二个节点是不是和第一个节点在同一个机架。
第二种算法
- 1,如果客户端所在服务器是dn,则首先写入当前dn,如果不是,则随机选择一台dn;
- 2,选择和dn1不同机架上的其他dn作为第二台dn;
- 3,选择不同dn1机架上的任意一台dn作为dn3;