赞
踩
初始化FileSystem
,client调用FileSystem
对象的open()
方法,打开一个HDFS文件。实际,FileSystem
对象是一个DistributedFileSystem
实例
DistributedFileSystem
通过RPC调用NameNode,获取一批文件block的位置列表。其中,每个block的副本所在的DataNode,是按照它们与客户端的距离排序的
DistributedFileSystem
向客户端返回一个FSDataInputStream
对象(open()
方法的返回结果),用于数据的读取。FSDataInputStream
中包含了DFSInputStream
对象,它管理着DataNode和NameNode的IO
以上对应图中的步骤1和2
客户端调用FSDataInputStream
对象的read()
方法,实际:存有block位置的DFSInputStream
会连接最近的DataNode,对该DataNode反复执行read()
,从而将数据从DataNode传到client。
①
DFSInputStream
发现DataNode故障,会记住该DataNode并从最近的另一个DataNode读取副本,以后保证不会反复从该DataNode读取block
②DFSInputStream
会对读取到的数据做checksum,如果发现数据损坏,会从其他DataNode读取副本并向NameNode通知损坏的block信息
DFSInputStream
完成block的读取,会关闭与该DataNode的连接。接着,创建与下一个block的最佳DataNode的连接,继续进行block的读取。
DFSInputStream
中存储的block位置可能是文件的部分block,它会按照需要从NameNode获取下一批block的位置信息。
以上对应步骤3、4和5
client读取数据完毕,则调用FSDataInputStream
对象的close()
方法关闭输入流
64MB
变成128MB
64 kb
512 byte
4 byte
的校验信息。因此,实际写入packet的chunk大小为516 byte
写过程会涉及chunk、packet、DataQueue/AckQueue这样的三层缓存:
DFSOutputStream
时,会先写入一个chunk大小的缓冲区。当数据写满一个chunk时,或遇到强制的flush()操作时,会计算校验和(checksum)DataStreamer
负责将DataQueue中的packet发送到最佳的DataNode中。同时,由于packet此时未确认写入成功,因此会被移动到AckQueue中等待写入确认。ResponseProcessor
会将packet从AckQueue中移除;否则, 会将其恢复到DataQueue的最前端,以保证没有packet丢失。因此,写入成功的packet在DataQueue和AckQueue中,应该都是不存在的。初始化FileSystem
对象,实际是一个DistributedFileSystem
实例。
clinet调用DistributedFileSystem
的create()
方法,创建一个HDFS文件。DistributedFileSystem
会通过RPC调用NameNode,进行文件创建的检查:client的权限检查、是否已存在该文件等。
通过检查后,NameNode会向EditLog写入一条新建文件的记录(WAL),然后DistributedFileSystem
会向client返回一个FSDataOutputStream
对象;否则,文件创建失败并向client抛出IOException
异常
FSDataOutputStream
对象中包含了DFSOutputStream
对象,DFSOutputStream
负责管理DataNode和NameNode的IO
对应图中的步骤1、2
client调用FSDataOutputStream
对象的write()方法向DataNode写入数据。实际,DFSOutputStream
会将数据划分成一个个packet,先将packet存如DataQueue中。
由DataStreamer
负责管理DataQueue,它挑选出一组适合存储副本的DataNode,并以此来要求NameNode分配适合新的block。这组DataNode之间会形成pipeline,packet通过pipeline进行传输
DataStreamer
将packet从DataQueue发送至第一个DataNode同时,DataStreamer
还会将未确认成功的packet移入AckQueue中,只有收到三个DataNode的ack packet后,ResponseProcessor
才会将packet从AckQueue中移除
对应步骤3、4、5
如果写入期间某个DataNode故障:
dfs.namenode.replication.min
,默认为1),则认为写入成功。后续通过异步的副本复制,来达到副本数要求。故障情况的处理
client完成数据写入,调用DistributedFileSystem
的close()
方法,关闭数据流
DistributedFileSystem
会调用通知NameNode文件写入完成前,等待确认。实际,只需要等待block满足最小副本数,就可以确认写入成功。
对应图中的步骤6、7
hflush()
HDFS提供了将缓存中的数据刷新到DataNode的方法:
hflush()
:Hadoop 1.x
中叫做sync()
,可以保证将数据写入DataNode的内存,但不保证数据写入磁盘 —— 存在断电数据丢失的风险其实,自己并不是很理解
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/456163Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。