1. 关于块跟副本

          hadoop中块是一种逻辑概念而副本才是真正的物理概念,即在DataNode中存储的数据块是以一个叫做的Replica来表示的,而在NameNode中则是以Block来表示。BlockInfoBlock的子类,主要用它来表示一个数据块,这个类中最重要的就是triplets这个数组对象了,假设数据块有i个副本,那么这个数组的长度为3*i,其中下标为3*i的元素记录了第i个副本所在的DataNode信息,而3*i+1以及3*i+2则分别记录了这个DataNode上前一个数据副本以及后一个数据副本对应的BlockInfo对象,这样NameNode中跟DataNode相关的对象就只用记录第一个数据块对应的BlockInfo就可以遍历该数据节点对应的所有数据块信息。

 

  2.BlockManager

          2.1 总体介绍

          BlockManager顾名思义,就是NameNode用来管理集群数据块的类。主要根据每次DataNode心跳发送过来的信息,来整理数据块。

          集群刚启动时,DataNode第一次发送心跳信息的时候获得所有数据块的全量汇报时,由于考虑到需要快速启动集群,所以不会根据心跳信息计算那些数据块需要复制、那些数据块需要删除,仅仅只是记录正常状态的数据块、正在构建的数据块以及损坏的数据块。对于后面增量汇报的数据块;

          对于后面的增量汇报,新增加的数据块可能是从其他的DataNode复制而来的也有可能是客户端写入的,对于前者,需要考虑更新BlockManager中相关信息,表明复制任务已经完成;如果是删除的数据块则要删掉NameNode中对应的元数据;

          当然每间隔6小时还会有一次DataNode关于块的全量汇报,这时会根据NameNode块的状态,将汇报的副本放入toAddtoRemovetoInvalidatetoCorrupttoUC这几个队列中,然后会根据这几个队列更新BolckManger中相关信息。

 

        2.2    数据结构

        corruptReplicas:损坏的副本集合;

        excessReplicateMap:多余的副本集合(例如降低副本数);

        invalidateBlocks:源自上面两个集合,等待删除的副本集合;

        neededReplications:等待复制的数据块;

        pendingReplications:已经生成复制请求的数据块;

        blocksMap:保存所有的blockInfo的信息。

 

        2.3    具体用例

        2.3.1         删除数据块

      删除文件的时候,由RPC调用BlockManagerremoveBlocks方法,期间会更新blocksMappendingReplicationsneededReplicationscorruptReplicas相应的信息,并将对应数据块的副本加入invalidateBlocks这个集合,最后向DataNode发送删除副本的指令。

 

           2.3.2         删除副本

      删除副本由很多种情况,除了上面的删除文件的时候要删除副本,至少还要考虑删除过多的副本以及删除损坏的副本。除了向DataNode发送删除副本的命令之外,还需要调用removeStoredBlock将副本信息从NameNode中删除。副本过多以及损坏副本有一点不同,前者需要DataNode发出相应心跳的时候才会调用removeStoredBlock方法,而后者在发送删除指令之前就会调用,主要是考虑到如果删除损坏副本的指令没有成功下达,下次心跳中损坏副本在NameNode中没有对应的信息,直接被标识为损坏副本。

         

          2.3.3         增加数据块

       当上一个数据块写入完成的时候,客户端向NameNode申请一个新的数据块,写入后面的数据,并且在blockMap中添加相应的键值对。由addBlockCollection方法处理。


2.3.4         增加副本

      客户端写入成功一个数据块,或者DataNode之间复制数据块成功之后,由心跳信息,发送给NameNode表示成功添加了一个数据块副本,由addStoredBlock方法响应、处理,并且更新neededReplicationsexcessReplicateMapcorruptReplicas这些集合。

 

           2.3.5         复制数据块

      触发块复制的情况也有很多,例如所有的数据块都在同一个机架上、完成写操作的文件没有足够的副本、有DataNode下线、pendingReplications队列上有超时的任务。这些情况对应的方法都会将这些数据块加入到needReplications队列中。最后如果DataNode能够及时响应,将会从pendingReplications队列中,删除已经成功复制的命令。