源码基于hadoop-3.3.0
1 BlockManager简介
BlockManager主要负责管理hadoop集群中的block信息。对于block的块,它始终保持着在任何事件下都能保持存活的副本数等于预期冗余。
BlockManager中存储的数据块信息包含两个部分:
- 数据块与存储这个数据块的数据节点存储的对应关系,这部分信息保存在数据块对应的BlockInfo对象的storages[]数组中, Namenode内存中的所有BlockInfo对象则保存在BlockManager.blocksMap字段中;
- 数据节点存储与这个数据节点存储上保存的所有数据块的对应关系, 这部分信息保存在DatanodeStorageInfo.blocks(数据结构为FoldedTreeSet)字段中,blocks是BlockInfo类型的,利用BlockInfo.storages[]字段 ,类型是DatanodeStorageInfo,可以通过blocks字段保存这个数据块存储上所有数据块对应的BlockInfo对象。
BlockManager管理Namenode中数据块的信息基本上都是通过FSNamesystem转到BlockManager上执行。
2 BlockManager的初始化
blockManager的初始化是在初始化FSNamesystem的过程中被初始化的。
...
// block manager needs the haEnabled initialized
// block管理器
this.blockManager = new BlockManager(this, haEnabled, conf);
// 由于dn的静态数据是通过heartbeat进行返回到dnManager的,因此这里直接返回一个heartbeatManager
this.datanodeStatistics = blockManager.getDatanodeManager().getDatanodeStatistics();
...
BlockManager构造函数确实挺长的,但主要是完成一些变量的初始化:
public BlockManager(final Namesystem namesystem, boolean haEnabled,
final Configuration conf) throws IOException {
this.namesystem = namesystem;
// 初始化DataNodeManager,该实例主要用来管理即将被移除(decommission)的dn和活跃的dn
datanodeManager = new DatanodeManager(this, namesystem, conf);
heartbeatManager = datanodeManager.getHeartbeatManager();
this.blockIdManager = new BlockIdManager(this);
// 默认1000
blocksPerPostpondedRescan = (int)Math.min(Integer.MAX_VALUE,
datanodeManager.getBlocksPerPostponedMisreplicatedBlocksRescan());
rescannedMisreplicatedBlocks =
new ArrayList<Block>(blocksPerPostpondedRescan);
startupDelayBlockDeletionInMs = conf.getLong(
DFSConfigKeys.DFS_NAMENODE_STARTUP_DELAY_BLOCK_DELETION_SEC_KEY,
DFSConfigKeys.DFS_NAMENODE_STARTUP_DELAY_BLOCK_DELETION_SEC_DEFAULT) * 1000L;
invalidateBlocks = new InvalidateBlocks(
datanodeManager.getBlockInvalidateLimit(),
startupDelayBlockDeletionInMs,
blockIdManager);
// Compute the map capacity by allocating 2% of total memory
// 初始化blocksMap
blocksMap = new BlocksMap(
LightWeightGSet.computeCapacity(2.0, "BlocksMap"));
placementPolicies = new BlockPlacementPolicies(
conf, datanodeManager.getFSClusterStats(),
datanodeManager.getNetworkTopology(),
datanodeManager.getHost2DatanodeMap());
storagePolicySuite = BlockStoragePolicySuite.createDefaultSuites
// dfs.namenode.reconstruction.pending.timeout-sec : 300s
pendingReconstruction = new PendingReconstructionBlocks(conf.getInt(
DFSConfigKeys.DFS_NAMENODE_RECONSTRUCTION_PENDING_TIMEOUT_SEC_KEY,
DFSConfigKeys.DFS_NAMENODE_RECONSTRUCTION_PENDING_TIMEOUT_SEC_DEFAULT)
* 1000L);
// 创建StoragePolicySatisfyManager:提供处理pathId的方法和方式,
// 包括external(独立与nn成为一个service)和none(disable)两种方式
createSPSManager(conf);
blockTokenSecretManager = createBlockTokenSecretManager(conf);
providedStorageMap = new ProvidedStorageMap(namesystem, this, conf);
this.maxCorruptFilesReturned = conf.getInt(
DFSConfigKeys.DFS_DEFAULT_MAX_CORRUPT_FILES_RETURNED_KEY,
DFSConfigKeys.DFS_DEFAULT_MAX_CORRUPT_FILES_RETURNED);
// 默认副本数:3
this.defaultReplication = conf.getInt(DFSConfigKeys.DFS_REPLICATION_KEY,
DFSConfigKeys.DFS_REPLICATION_DEFAULT);
// 最大副本数:512
final int maxR = conf.getInt(DFSConfigKeys.DFS_REPLICATION_MAX_KEY,
DFSConfigKeys.DFS_REPL