void heartbeatCheck ( ) { if ( ! getNameNode ( ) . shouldCheckHeartbeat ( ) ) { // not to check dead nodes. return ; } boolean allAlive = false ; while ( ! allAlive ) { boolean foundDead = false ; DatanodeID nodeID = null ; // locate the first dead node. synchronized ( heartbeats ) { for ( Iterator < DatanodeDescriptor > it = heartbeats . iterator ( ) ; it . hasNext ( ) ; ) { DatanodeDescriptor nodeInfo = it . next ( ) ; if ( isDatanodeDead ( nodeInfo ) ) { foundDead = true ; nodeID = nodeInfo ; break ; } } } // acquire the fsnamesystem lock, and then remove the dead node. if ( foundDead ) { writeLock ( ) ; try { synchronized ( heartbeats ) { synchronized ( datanodeMap ) { DatanodeDescriptor nodeInfo = null ; try { nodeInfo = getDatanode ( nodeID ) ; } catch ( IOException e ) { nodeInfo = null ; } if ( nodeInfo != null && isDatanodeDead ( nodeInfo ) ) { NameNode . stateChangeLog . info ( "BLOCK* NameSystem.heartbeatCheck: " + "lost heartbeat from " + nodeInfo . getName ( ) ) ; removeDatanode ( nodeInfo ) ; nodeInfo . setStartTime ( now ( ) ) ; } } } } finally { writeUnlock ( ) ; } } allAlive = ! foundDead ; } }
Check if there are any expired heartbeats and if so whether any blocks have to be re - replicated . While removing dead datanodes make sure that only one datanode is marked dead at a time within the synchronized section . Otherwise a cascading effect causes more datanodes to be declared dead .