当前位置:编程学习 > JAVA >>

HDFS--DFSClient中的读Block机制

BlockReader中的readChunk用于从DataNode中读取块信息和块数据(chunk=block);read方法如果发现块数据校验码无误,就向DataNode发送OP_STATUS_CHECKSUM_OK表示无错误发生。
 
 
 
 
DFSInputStream是DFSClient用于读取文件块的方法,其内包含了blockReader用于与DataNode交互(在readBuffer中调用BlockReader的read方法读取块内容)。
在读取文件块时,采用预读取方式,根据访问局部性原理,从offset开始(offset初始为0,即文件头),将长度为prefetchSize的块集合信息读到localBlocks(这是一个LocalBlock列表,可以视为缓存。LocalBlock是由{Block,DatanodeInfo[]}构成的pair,用于定位块,继承于Writeable)中,即
[java]  
callGetBlockLocations(namenode, src, offset, prefetchSize);  
如果读取的内容不在localBlocks中,就从namenode中读取offset开始,长度为prefetchSize的块,并加入到localBlocks缓存中。
 
 
 
LocalBlock与BlockReader的关系:LocalBlock用于定位Block,而BlockReader用于读取该Block的内容。
当需要读取一个Block时
[java] 
public synchronized int read(byte buf[], int off, int len)  
先调用blockSeekTo获取块所在的datanode建立连接并根据localBlock获取相应的BlockReader(内部流程:
根据offset获取LocalBlock-->调用chooseDatanode获取块所在的DataNode-->与datanode建立连接;调用localBlock的getBlock()获取block,根据这个block创建一个BlockReader)-->调用readBuffer,用blockReader的read读取block(注:BlockReader的read在每次读取时都会调用checksumOk对block进行校验)
 
 
当需要读取多个块
[java]  
int read(long position, byte[] buffer, int offset, int length)  
(注:position为要读取的文件开始位置,offset是从buffer的offset位置开始存)时,首先调用getBlockRange获取length范围内的所有块的LocalBlock,再对于每个LocalBlock依次调用fetchBlockByteRange读取相应的块到buffer中(执行流程是先根据LocalBlock生成一个BlockReader对象,在调用这个reader的readerAll方法读取块到buffer中)
补充:软件开发 , Java ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,