namenode上块管理--BlockMap

2019-03-28 13:08|来源: 网络

BlockInfo继承自Block类,是块的信息类,含以下变量:
private INodeFile inode;//块所在的文件(在INodeFile中有INodeFile.blocks表示构成此文件的所有块)
private Object[] triplets;//此块所在的Datanodes三元组,类似于双向链表
triples的赋值方法:

this.triplets = new Object[3*replication];//replicaton是此块的副本数

可以看出triples数组存放了块的每个副本所在的Datanode,块i所在的Datanode对应为triples[3*i],而triples[3*i+1]表示此块所在Datanode上的前一个块信息,triples[3*i+2]表示此块所在的DataNode上的后一个块信息(DatanodeDescriptor将Datanode上的块串成一个表,DatanodeDescriptor上保存了表头信息BlockInfo blockList)。因此triples[3*i]为DatanodeDescriptor类型,triples[3*i+1]、triples[3*i+2]是BlockInfo类型。
通过此三元组可以实现如下的映射:INode<-->BlockInfo,BlockInfo<-->DatanodeDescriptor。由于DatanodeDescriptor上有

 private volatile BlockInfo blockList = null;

可以在Datanode出现错误时,根据blockList进行块备份。

文件的每个块的BlockInfo中保存了这个块的所有副本所在的Datanode表triples,在每个Datanode的描述类DatanodeDescriptor中保存了由Datanode上的所有块构成的一个块链。Datanode上的块链是用triples实现的。

一些重要的方法:

boolean addNode(DatanodeDescriptor node);//添加一个新的Datanode到triples,即此块多备份一个副本。

int ensureCapacity(int num);//确保再添加num个块到triples时,triples长度够用。必要时对triples进行扩充(扩充是新new一个长度符合的数组,然后再System.arrayCopy。由于每个块的副本数不多,所以这种扩充方式还是可以接受的)。

int findDatanode(DatanodeDescriptor dn);//获得Datanode dn上的块在triples中的位置
BlockInfo getNext(int index);//获取在Datanode triples[3*index]上块index的下一个块信息
boolean removeNode(DatanodeDescriptor node);//将node对应的BlockInfo从triples中清除掉:将triples的最后一个块x移到node对应的块的位置,同时将x在Datanode中的前驱后继也都移过来,这样就替换掉了node。这会造成triples最后几个块空。所以用numNodes()得到triples的有效大小。
int numNodes();//获得此块有效的副本数。
int getCapacity();//返回triples的实际大小。
int listCount(DatanodeDescriptor dn);//在dn上,统计当前块后面还有几个块。
boolean listIsConsistent(DatanodeDescriptor dn);//在dn上,检测从当前块开始,后面的块之间的对应关系(双向链表)是否一致。即blockA.next.previous==blockA

BlockInfo listInsert(BlockInfo head, DatanodeDescriptor dn) {//用于将此块(本类this)插入到dn的块链最前面
      int dnIndex = this.findDatanode(dn);
      assert dnIndex >= 0 : "Data node is not found: current";
      assert getPrevious(dnIndex) == null && getNext(dnIndex) == null :
              "Block is already in the list and cannot be inserted.";
      this.setPrevious(dnIndex, null);//在Datanode中,设置此块前面无块
      this.setNext(dnIndex, head);//在Datanode中,设置此块下一个块为Datanode块链的块首
      if(head != null)
        head.setPrevious(head.findDatanode(dn), this);//设置Datanode上的块首的前一个块为当前块
      return this;
    }

BlockInfo listRemove(BlockInfo head, DatanodeDescriptor dn) {
//将此块从Datanode的块链中删除。类似于双向链表删除的方式,将dn对应的块从triples中‘移出’(通过修改原本的前驱后继)。
      if(head == null)
        return null;
      int dnIndex = this.findDatanode(dn);
      if(dnIndex < 0) // this block is not on the data-node list
        return head;
      BlockInfo next = this.getNext(dnIndex);
      BlockInfo prev = this.getPrevious(dnIndex);
      this.setNext(dnIndex, null);
      this.setPrevious(dnIndex, null);
      if(prev != null)
        prev.setNext(prev.findDatanode(dn), next);
      if(next != null)
        next.setPrevious(next.findDatanode(dn), prev);
      if(this == head)  // removing the head
        head = next;
      return head;
    } 

相关问答

更多
  • namenode确实保留了一些关于文件的状态(名称,路径,大小,块大小,块ID等),而不是块的位置的物理位置。 当数据节点启动时,它们实际上树遍历dfs数据目录,发现它们拥有的所有文件块,一旦完成,就向名称节点报告它所承载的块。 namenode构建文件映射以阻止来自每个数据节点的报告的位置。 这是集群首次启动时有时需要几分钟才能退出安全模式的原因之一 - 如果您有大量文件,则每个数据节点可能需要一些时间才能进行树步行并发现阻塞它主机。 The namenode does preserve some sta ...
  • 这很简单 - 格式化你的名字节点 mcbatyuk:hadoop bam$ bin/hadoop namenode -format Warning: $HADOOP_HOME is deprecated. 12/04/11 21:04:55 INFO namenode.NameNode: STARTUP_MSG: /************************************************************ STARTUP_MSG: Starting NameNode STA ...
  • 这里持续意味着名称节点将有关块信息的信息存储在内存中,而不是将这些信息保存在文件系统或HDFS或任何数据库或任何类型的外部存储中。 考虑一下它是否在文件系统上持续存在,那么下一次启动群集时,您将获得所有信息。 但是,你认为名称节点的信息会是最新的吗? 假设一个数据节点可能由于硬件故障而关闭,因此名称节点的信息将失效。 Here persistently means that name node would store information about block information in memory ...
  • 1)用hdfs://192.168.100.101:9001替换fs.default.name的值 2)检查你的site.xml文件,无论你是否在其中错误地添加了空间 1) Replace value of fs.default.name with hdfs://192.168.100.101:9001 2) Check your site.xml files, whether in value you have mistakenly added space in between
  • 这里有两件事要考虑, 1- Recovery through SecondaryNameNode 2- Recovery through redundant NameNode 在hadoop-1.x我们在SecondaryNameNode上有一个概念,它包含NameNode元数据的副本。 如果您的NameNode出现故障,您可以使用SecondaryNameNode存储的元数据副本,并在NameNode再次启动后使用它来恢复您的工作。 使用hadoop-2.x(HA)您可以拥有多个NameNode。 如果 ...
  • 因为我在这里解决了它是如何做到的。 只需输入以下内容然后输入数据节点即可运行(用您自己的替换hadoop_install) $ HADOOP_INSTALL / bin / hdfs dfsadmin -refreshNodes since I fixed it here is how I did it. just typed the following and then data nodes where up and running (replace hadoop_install with your ow ...
  • 最后,我得到了答案。 作为开发人员,由于限制,无法执行dfsadmin命令。 为了检查namenode的可用性,我在shellcript中使用了以下if循环来完成这个操作。 它不会告诉您namenode是否处于活动状态,但通过循环,您可以轻松地相应地执行所需的程序。 if hdfs dfs -test -e hdfs://namenodeip/* ; then echo exist else echo not exist fi Finally, I got an answer to this. As a ...
  • 我假设您已屏蔽并共享您的网址 hdfs://vikasXXX.XX.XX.XX:X000 我认为它无法通过名称识别您的机器。 尝试使用localhost并检查它是否有效。 hdfs://localhost:8020 I assume that you have masked and shared your URL hdfs://vikasXXX.XX.XX.XX:X000 I think it is not recognizing your machine by name. Try using localh ...