• 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。

  • 相关阅读:
    socket 第一课
    _getitem__ __setitem__ __delitem__ __len__
    单继承&多继承 注意点
    面对对象 类&对象
    异常检测
    模块导入
    序列化模块注意点 json&pickle
    re模块
    filter和map
    Maven入门
  • 原文地址:https://www.cnblogs.com/sidmeng/p/2390732.html
Copyright © 2020-2023  润新知