版权声明:转载请注明出处 https://blog.csdn.net/qiaojialin/article/details/84396025
NameNode
- FSNamesystem
// 包括三个守护线程
private void initialize(NameNode nn, Configuration conf){
// 心跳监控
this.hbthread = new Daemon(new HeartbeatMonitor());
// 租约管理
this.lmthread = new Daemon(leaseManager.new Monitor());
// 复制文件块
this.replmon = new ReplicationMonitor();
this.replthread = new Daemon(replmon);
}
// NameNode 接收到 DataNode 的 block 回复后,更新等待列表和 block 位置信息。
pendingReplications.remove(block);
addStoredBlock(block, node, delHintNode );
-
PendingReplicationBlocks:保存当前正在复制的块的状态。守护线程 PendingReplicationMonitor 记录复制超时的块。
- PendingBLockInfo,用来记录正在复制的副本数量,每复制好一个就减一个,减到 0 就复制好了。
-
ReplicationMonitor:定期启动复制工作
- UnderReplicatedBlocks:保存当前需要复制的块的状态。根据一个块的现有状态(当前副本数,失联副本数,预期副本数)设定优先级,共有三个优先级。
- computeDatanodeWork():计算 DataNode 的任务,在下次心跳时给 DataNode。包括两种任务:computeReplicationWork(复制任务),computeInvalidateWork(失效任务)。
DataNode
每个 DataNode 启动一个 DataXceiverServer 守护线程,里边实际完成写磁盘的是 DataXceiver,
-
DataXceiver
writeBlock() { // 给上一个节点回复 Text.writeString(replyOut, datanode.dnRegistration.getName()); // 读取一个 block blockReceiver.receiveBlock(mirrorOut, mirrorIn, replyOut, mirrorAddr, null, targets.length); { // 将 block 中的每一个 Packet 转发到下个节点并写磁盘 while (receivePacket() > 0) {} } // 将接收到的 block 加到 receivedBlockList 中,准备通知 NameNode datanode.notifyNamenodeReceivedBlock(block, DataNode.EMPTY_DEL_HINT); }
-
DataNode
// 通知 NameNode 已接收的 block namenode.blockReceived(dnRegistration, blockArray, delHintArray);