数据块管理 #
- HDFS文件系统的目录树以及文件的数据块索引,文件的数据块索引信息保存在 INodeFile.blocks 字段
- 数据块和数据节点的对应关系,由 Datenode启动时,上报给Namenode
Block、Replica、BlocksMap #
BlocksMap #
Replica类状态 #
数据块副本状态 #
通过BlockManager中的数据结构、不同的数据块副本类(例如BlockUnderConstruction 和 Block)以及副本所在Datanode 的状态(Datanode 处于撤销状态)来记录数据块副本的状态
BlockManager #
postponedMisreplicatedBlocks #
当
Namenode
发生错误并进行了Active
与Standby
切换时,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 队列中以执行 数据块副本复制流程。
- 客户端完成了一个文件的写操作,Namenode会检查这个文件包含的所有数据块是否有足够的副本数量,如果不足则加入 neededReplications 队列中。
- 当Namenode 执行一个Datanode 的撤销操作时,会将这个Datanode 上保存的所有副本进行复制, 也就是将这些副本加入neededReplications队列中。
- pendingReplications 队列中保存的数据块复制任务超时,会将这些任务重新加入neededReplications队列中。
块汇报 #
Namenode中数据块与数据节点的对应关系并不持久化在fsimage文件中,
而是由Datanode定期块汇报到Namenode,然后由Namenode重建内存中数据块与数据节点的对应关系。
BlockManager.blocksMap: 数据块与数据节点存储的对应关系
DatanodeStorageInfo.blockList: 数据节点存储与数据块的信息