除了对外提供的接口,NameNode上还有一系列的线程,不断检查系统的状态,下面是这些线程的功能分析。
在NameNode中,定义了如下线程:
Daemon hbthread= null; // HeartbeatMonitor thread
publicDaemon lmthread = null; // LeaseMonitor thread
Daemon smmthread= null; // SafeModeMonitor thread
publicDaemon replthread = null; // Replication thread
privateDaemon dnthread = null;
PendingReplicationBlocks中也有一个线程:
Daemon timerThread= null;
NameNode内嵌的HTTP服务器中自然也有线程,这块我们就不分析啦。
HttpServer infoServer;
心跳线程用于对DataNode的心态进行检查,以间隔heartbeatRecheckInterval运行heartbeatCheck方法。如果在一定时间内没收到DataNode的心跳信息,我们就认为该节点已经死掉,调用removeDatanode(前面分析过)将DataNode标记为无效。
租约lmthread用于检查租约的硬超时,如果租约硬超时,调用前面分析过的internalReleaseLease,释放租约。
smmthread运行的SafeModeMonitor我们前面已经分析过了。
replthread运行ReplicationMonitor,这个线程会定期调用computeDatanodeWork和processPendingReplications。
computeDatanodeWork会执行computeDatanodeWork或computeInvalidateWork。computeDatanodeWork从neededReplications中扫描,取出需要复制的项,然后:
l 检查文件不存在或者处于构造状态;如果是,从队列中删除复制项,退出对复制项的处理(接着处理下一个);
l 得到当前数据块副本数并选择复制的源DataNode,如果空,退出对复制项的处理;
l 再次检查副本数(很可能有DataNode从故障中恢复),如果发现不需要复制,从队列中删除复制项,退出对复制项的处理;
l 选择复制的目标,如果目标空,退出对复制项的处理;
l 将复制的信息(数据块和目标DataNode)加入到源目标DataNode中;在目标DataNode中记录复制请求;
l 从队列中将复制项移动到pendingReplications。
可见,这个方法执行后,复制项从neededReplications挪到pendingReplications中。DataNode在某次心跳的应答中,可以拿到相应的信息,执行复制操作。
computeInvalidateWork当然是用于删除无效的数据块。它的主要工作在invalidateWorkForOneNode中完成。和上面computeDatanodeWork类似,不过它的处理更简单,将recentInvalidateSets的数据通过DatanodeDescriptor.addBlocksToBeInvalidated挪到DataNode中。
dnthread执行的是DecommissionedMonitor,它的run方法周期调用decommissionedDatanodeCheck,再到checkDecommissionStateInternal,定期将完成Decommission任务的DataNode状态从DECOMMISSION_INPROGRESS改为DECOMMISSIONED。
PendingReplicationMonitor中的线程用于对处在等待复制状态的数据块进行检查。如果发现长时间该数据块没被复制,那么会将它挪到timedOutItems中。请参考PendingReplicationBlocks的讨论。
infoServer的相关线程我们就不分析了,它们都用于处理HTTP请求。
上面已经总结了NameNode上的一些为特殊任务启动的线程,除了这些线程,NameNode上还运行着RPC服务器的相关线程,具体可以看前面章节。
在我们开始分析Secondary NameNode前,我们给出了以NameNode上一些状态转移图,大家可以通过这个图,更好理解NameNode。
NameNode:
DataNode:
文件:
Block,比较复杂:
上面的图不是很严格,只是用于帮助大家理解NameNode对Block复杂的处理过程。
稍微说明一下,“Block in initedDataNode”表明这个数据块在一个刚初始化的DataNode上。“Block in INodeFile”是数据块属于某个文件,“Block in INodeFileUnderConstruction” 表明这数据块属于一个正在构建的文件,当然,处于这个状态的Block可能因为租约恢复而转移到“Block in Recover”。右上方描述了需要复制的数据块的状态,UnderReplicatedBlocks和PendingReplicationBlocks的区别在于Block是否被插入到某一个DatanodeDescriptor中。Corrupt和Invalidate的就好理解啦。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。