2. 数据块管理

数据块管理 #

  • HDFS文件系统的目录树以及文件的数据块索引,文件的数据块索引信息保存在 INodeFile.blocks 字段
  • 数据块和数据节点的对应关系,由 Datenode启动时,上报给Namenode

Block、Replica、BlocksMap #

BlocksMap #

Replica类状态 #

数据块副本状态 #

通过BlockManager中的数据结构、不同的数据块副本类(例如BlockUnderConstruction 和 Block)以及副本所在Datanode 的状态(Datanode 处于撤销状态)来记录数据块副本的状态

BlockManager #

postponedMisreplicatedBlocks #

Namenode发生错误并进行了ActiveStandby 切换时,Namenode中保存的多余副本 不能直接被删除,需要先放入postponedMisreplicatedBlocks队列中,直到这个数据块的所有 副本所在的Datanode都进行了块汇报

这样设计呢?是考虑到下面这个场景。

  • blockA有两个副本,副本1在datanodel上,副本2在datanode2上。
  • 这时,namenodel发出删除指令,删除datanodel上的副本1。
  • 发出删除指令后,namenodel发生错误,切换至namenode2。
  • 这时datanodel并没有进行块汇报,namenode2并不知道datanodel上已经删除了副 本1。所以namenode2向datanode2发出删除操作。
  • datanode2删除复本2,数据块的所有副本都被删除了,数据块也就丢失了。

数据块副本状态 #

ReplicationMonitor #

computeReplicationWork() #

增删改查 #

BlockManager 最重要的功能之一就是维护 Namenode 内存中的数据块信息,BlockManager中存储的数据块信息包含两个部分

添加数据块 #

添加副本 #

删除数据块 #

删除副本 #

数据块复制 #

Namenode 会在以下三种情况下将一个数据块副本加入 neededReplications 队列中以执行 数据块副本复制流程。

  1. 客户端完成了一个文件的写操作,Namenode会检查这个文件包含的所有数据块是否有足够的副本数量,如果不足则加入 neededReplications 队列中。
  2. 当Namenode 执行一个Datanode 的撤销操作时,会将这个Datanode 上保存的所有副本进行复制, 也就是将这些副本加入neededReplications队列中。
  3. pendingReplications 队列中保存的数据块复制任务超时,会将这些任务重新加入neededReplications队列中。

块汇报 #

Namenode中数据块与数据节点的对应关系并不持久化在fsimage文件中,
而是由Datanode定期块汇报到Namenode,然后由Namenode重建内存中数据块与数据节点的对应关系。
BlockManager.blocksMap: 数据块与数据节点存储的对应关系
DatanodeStorageInfo.blockList: 数据节点存储与数据块的信息

增量块汇报 #