一、读取数据流程
1、原理图
2、流程剖析
a)客户端首先调用DistributedFileSystem对象的open方法,去和namenode建立rpc通信,请求namenode
返回文件的元信息。
b)namenode得到请求,会在内存中寻找文件元信息。找到后给客户
端返回部分(读取文件较大)或全部的block列表,即FSDataInputStream对象。
c)客户端调用FSDataInputStream对象的read()方法,从离客户端最近的block副本进行block块的读取,
直到这个block块的所有信息读取完毕,然后再进行该block的校验,校验成功则读取下一个block块数据,校
验失败则通知namenode并从另一个副本读取数据。
d)如果block列表中数据读取完毕,文件读取还没有结束,DistributedFileSystem对象会从namenode那儿
获取下一批的block列表,再次进行block数据的读取。
e)文件读取完毕,客户端会将所有block块拼成一个完整的最终文件,然后调用FSDataInputStream对象的
close()方法,关闭输入流,读取结束。
注意:
1、namenode返回的block列表中的block是经过了排序的,离客户端近的排在前面,心跳机制中超时汇报的排
在后面。
2、读取实际上是多线程方式并行读取,流程中所说的一个一个block块读取实际上是从单线程的角度考虑的,
这样方便描述。
二、写入数据流程
1、原理图
2、流程剖析
a)客户端首先调用DistributedFileSystem对象的create方法,去和namenode建立rpc通信,请求写入数
据。
b)namenode收到请求,会进行诸如文件是否存在、用户是否拥有相应权限等一系列的检查。若检查通过, 则
为该次上传建立一次记录,并返回给客户端一个FSDataOutputStream对象;检查不通过,返回给客户端异常
信息。
c)客户端拿到FSDataOutputStream对象后先对文件进行线性切块,然后会调用FSDataOutputStream对象的
write()方法,开始上传第一个block块,上传前会在block的三个副本对应的机器之间建立一条pipeline通
道。每次成功写入一个packet到第一台机器上,三台机器立马通过pipeline进行数据的同步,每次第一台机子
通过pipeline成功向后传一个packet,就会放入一个ack packet到应答队列等待应答。
d)每一个block的最后一个packet上传完毕后,datanode给应答队列返回应答信息,然后client会请求
namenode上传下一个block数据,直到所有block上传完毕。
e)上传完毕后,客户端调用FSDataOutputStream对象的close()和flush()关闭刷新输出流,然后通知
namenode上传完毕。
注意:
数据的写入以packet为单位,每个packet大小为64KB,这些packet存在数据队列中。
上传时的datanode宕机问题:
1、pipeline关闭,所有确认队列相关数据包发送到数据队列头部重新上传。
2、宕机节点移除,其他数据节点形成新的管线,继续block未完数据的上传,完成结束后namenode会自
动安排一个新的副本以达到冗余度要求。
3、多个节点宕机,只要上传后副本数满足属性hdfs-site.xml文件中dfs.relication.min属性确认的
最少副本数要求,就算上传成功。