ReplicationMonitor thread could stuck for long time and loss data with little probability. Consider the typical scenario：
(1) create and close a file with the default replicas(3);
(2) increase replication (to 10) of the file.
(3) delete the file while ReplicationMonitor is scheduling blocks belong to that file for replications.
if ReplicationMonitor stuck reappeared, NameNode will print log as:
This is because 2 threads (#NameNodeRpcServer and #ReplicationMonitor) process same block at the same moment.
(1) ReplicationMonitor#computeReplicationWorkForBlocks get blocks to replicate and leave the global lock.
(2) FSNamesystem#delete invoked to delete blocks then clear the reference in blocksmap, needReplications, etc. the block's NumBytes will set NO_ACK(Long.MAX_VALUE) which is used to indicate that the block deletion does not need explicit ACK from the node.
(3) ReplicationMonitor#computeReplicationWorkForBlocks continue to chooseTargets for the same blocks and no node will be selected after traverse whole cluster because no node choice satisfy the goodness criteria (remaining spaces achieve required size Long.MAX_VALUE).
During of stage#3 ReplicationMonitor stuck for long time, especial in a large cluster. invalidateBlocks & neededReplications continues to grow and no consumes. it will loss data at the worst.
This can mostly be avoided by skip chooseTarget for BlockCommand.NO_ACK block and remove it from neededReplications.