hadoop hdfs总结 NameNode部分 1

    一、INode部分

    先画了一下类图,比较简单。  

   

    1、INode是抽象类,有两个子类,INodeFile和INodeDirectory,对了了file和directory。

    INode定义了一些基本属性,如name,parent,modificationTime,accessTime,还有ugi信息等。INode implements Comparable是可比较的,可以通过二分查找找到树状结构中对应的INode。

    此外,INode中重要的方法是public final ContentSummary computeContentSummary() ,计算该INode树状结构下的统计数据,如file数,dir数,length等。

    INode中还有一个重要方法 static byte[][] getPathComponents(String[] strings) 该方法的作用是获取文件名称,按照seperate 即"/",每个path存在一个byte[]数组中。

    2、INodeDirectory定义了Directory,基本属性有private List<INode> children 是所有树状结构底下的INodeFile和INodeDirectory,INodeDirectory的一些重要方法:

        (1)INode removeChild(INode node)   通过二分查找找到对应的子INode对象,从children中删除,并返回该对象

        (2)void replaceChild(INode newChild)  同上,只不过是替换

        (3)private INode getChildINode(byte[] name) 通过二分查找获得INode对象

        (4)<T extends INode> T addChild(final T node, boolean inheritPermission) 插入一个INode对象到队列中,并且按顺序插入,其中重要的代码是        

int low = Collections.binarySearch(children, node.name);
    if(low >= 0)
      return null;
    node.parent = this;
    children.add(-low - 1, node); 

       (5)<T extends INode> INodeDirectory addToParent  插入一个INode到相关的parent中,并且更新该parent对应的INode children队列

       (6)DirCounts spaceConsumedInTree(DirCounts counts)  计算磁盘使用空间,递归计算

         (7)int collectSubtreeBlocksAndClear(List<Block> v) 将所有树状结构下的block返回,用于删除以后对block做处理。

       (8)int getExistingPathINodes(byte[][] components, INode[] existing) 这个方法个人认为比较重要,作用是从components[]中获取存在的INode数组,意思是components是一个全路径path,有可能存在该路径,也可能不存在,通过该函数找到存在的path,形成INode对象返回

int getExistingPathINodes(byte[][] components, INode[] existing) {
assert compareBytes(this.name, components[0]) == 0 :
"Incorrect name " + getLocalName() + " expected " + components[0];

INode curNode = this;
int count = 0;
int index = existing.length - components.length;
if (index > 0)
index = 0;
while ((count < components.length) && (curNode != null)) {
if (index >= 0)
existing[index] = curNode;
if (!curNode.isDirectory() || (count == components.length - 1))
break; // no more child, stop here
INodeDirectory parentDir = (INodeDirectory)curNode;
curNode = parentDir.getChildINode(components[count + 1]);
count += 1;
index += 1;
}
return count;
}

    3、INodeDirectoryWithQuota 继承自INodeDirectory,加入了Quota,如果超出Quota会抛出相应的ExceededException 异常。

   4、INodeFile INodeFile对应了Block,HDFS对每个File复制了多分副本,通过策略放在不同的DataNode上,同时每个INodeFile对应了多个Block,默认情况下每个Block64M。

        INodeFile中主要的属性有protected BlockInfo blocks[],protected short blockReplication,protected long preferredBlockSize

        blocks在blockMap中会详细介绍,就是该INodeFile对应的Block。

        INodeFile中的一些重要方法:

       (1)Block getLastBlock()    获得最后一个Block,由于目前HDFS支持append,所以获得最后一个Block进行append操作

       (2)void addBlock(BlockInfo newblock)  向该INodeFile对应的Block数组中最后位置添加一个Block

       (3)int collectSubtreeBlocksAndClear(List<Block> v)  将所有Block放在列表中,如删除某个目录下所有文件,就需要获得所有Block,在BlockMap中进行删除。      

  int collectSubtreeBlocksAndClear(List<Block> v) {
    parent = null;
    for (Block blk : blocks) {
      v.add(blk);
    }
    blocks = null;
    return 1;
  }

       设置parent=null 使得资源得以通过GC回收。

     (4)Block getPenultimateBlock() 获得倒数第二个Block

    5、INodeFileUnderConstruction 说明该INodeFile对应的Block正在写入DataNode。INodeFile处于UnderConstruction状态有几种情况,如正写入文件,lease recovery等。当然只能对最后一个Block进行append。

         主要属性有 String clientName; 正在写入的Client名称。  private int primaryNodeIndex = -1; 当进行leaseRecovery时,会选出primary通过primary向其它DataNode发送Recovery信息。

         private DatanodeDescriptor[] targets = null;   target是最后一个Block对应的DataNode位置,该target由一定算法获得。在后面会分析。

        重要的方法有:

       (1)void setTargets(DatanodeDescriptor[] targets)  设置该INodeFile对应Block所在的DataNode(DatanodeDescriptor是DataNode的抽象)

       (2)void addTarget(DatanodeDescriptor node)  将新的DataNode加入到target中

       (3)INodeFile convertToInodeFile() 如果DataNode获得所有数据并成功回报给NameNode后,将INodeFIleUnderConstruction状态转化为正常状态。

         (4) void removeBlock(Block oldblock) 将最后一个Block删除,原因可能是由于Block传输过程中出错,被abandon掉,也可能是进行recovery中发现时间戳不一致。

       (5)synchronized void setLastBlock(BlockInfo newblock, DatanodeDescriptor[] newtargets)  设置最后一个Block,并且设置对应的DataNode,在NameNode的Append中使用。

       (6)void assignPrimaryDatanode()   在LeaseRecovery过程中使用,到LeaseRecovery过程会详细解释,这个方法就是找到一个alive的DataNode作为primary,来进行Lease Recovery。

      INode部分至此结束,INode+BlockMap构成了NameNode中主要的数据结构,其它的操作都是围绕这这两个数据结构进行处理,后面将会总结BlockMap。

原文地址:https://www.cnblogs.com/sidmeng/p/2390732.html