hdfs学习笔记

1. dfsclient


packet的大小,65557,一个packet有127个chunk,一个chunk有512字节,他的checksum为4个字节,
写入的时候,每512个字节调用一次加入到packet(最后一个可以不满512字节,close或者flush的时候)
每个block有多个packet, 默认64M
客户端发送读取请求在DFSClient的newBlockReader中


2.namenode

 调用namenode增加一个新的块

org.apache.hadoop.hdfs.protocol.ClientProtocol.addBlock 

   

调用namenode定位一个块

 

public abstract org.apache.hadoop.hdfs.protocol.LocatedBlock 

  

向namenode申请create一个文件:

public abstract void org.apache.hadoop.hdfs.protocol.ClientProtocol.create

 

inode体系是用loadfsimage中来的,也可能中途增加再写入回去。

 3.datanode

ResponseProcessor会处理ack队列,BlockReceiver的verifyChunks会校验chekcsum

 

向本地磁盘写入数据和向另外一个datanode发送数据都在BlockReceiver的receivePacket()中,先向datanode发送数据,然后本地再校验checksum和写入数据到磁盘,退出这个方法后,再向datanode写一个0,表示传送完成。

 

每次写入数据到磁盘(一次receive后,都会向PacketResponder的ackQueue入队一个ack消息,然后另外一个线程取出来,并且如果不是最后一个datanode,就等待后面的datanode的ack。然后再看是否这个block全部搞完了,搞完了就通知下namenode,在发送ack到前面一个datanode或者客户端) 

 

3.1  在blockReceiver.receiveBlock

在blockReceiver.receiveBlock方法中,主要完成两件事情

 a.启动一个PacketResponder
 b.receivePacket
       a.将消息转发给下一台
       b.写入文件到临时文件
       c.向PacketResponder的队列加入一个消息


 

PacketResponder从队列取本地或者下一台的返回(本地的直接从队列取出,下一台的从mirrorIn中取出)
lastPacketInBlock的判断方式是:


boolean lastPacketInBlock = (buf.get() != 0); (看下包的协议是怎么规定的)
 

当发现是最后一个packet的时候,调用:
datanode.data.finalizeBlock(block);


这里会将临时目录的文件移动到current目录,并删除临时目录的文件.

 

writer.syncFs();是刷新数据到服务器的临时目录上


writer.close();是让服务器完成finalizeBlock的动作,然后才可以查询到。

这里先写临时目录,很大一个原因是这样拷贝一次后,新的快将是一个连续的磁盘快,提高后来读取的效率。

 

事实上,hbse的每次hlog的写入,都是writer.syncFs();写入到服务器上去了的。然后在日志滚动等的时候调用writer.close()正式完成写入。当然,如果写入的log大小超过了一个块,也会写到服务器上并可以查询的。因为上面的分析中,是lastpacket(of a block)的时候从临时变为正式。但这些快都是一个文件的,只有rollLog后才会有新的文件.

 

inode体系没有datanode的信息,在FSNameSystem.getBlockLocationsInternal中(读取文件的块信息),从FSNameSystem的blocksMap中取出来的。放在DatanodeDescriptor中,再把DatanodeDescriptor各个放到machineSet,最后和block一起创建LocatedBlock,把所有的快放到LocatedBlocks中,再通过clusterMap排序后返回.

你可能感兴趣的:(hdfs)