HDFS-10987. Make Decommission less expensive when lot of blocks present. Contributed by Brahma Reddy Battula.

This commit is contained in:
Kihwal Lee 2016-10-13 13:52:49 -05:00
parent fdce515091
commit 332a61fd74

View File

@ -388,6 +388,10 @@ private class Monitor implements Runnable {
* The number of blocks that have been checked on this tick. * The number of blocks that have been checked on this tick.
*/ */
private int numBlocksChecked = 0; private int numBlocksChecked = 0;
/**
* The number of blocks checked after (re)holding lock.
*/
private int numBlocksCheckedPerLock = 0;
/** /**
* The number of nodes that have been checked on this tick. Used for * The number of nodes that have been checked on this tick. Used for
* statistics. * statistics.
@ -418,6 +422,7 @@ public void run() {
} }
// Reset the checked count at beginning of each iteration // Reset the checked count at beginning of each iteration
numBlocksChecked = 0; numBlocksChecked = 0;
numBlocksCheckedPerLock = 0;
numNodesChecked = 0; numNodesChecked = 0;
// Check decom progress // Check decom progress
namesystem.writeLock(); namesystem.writeLock();
@ -451,7 +456,8 @@ private void check() {
iterkey).iterator(); iterkey).iterator();
final LinkedList<DatanodeDescriptor> toRemove = new LinkedList<>(); final LinkedList<DatanodeDescriptor> toRemove = new LinkedList<>();
while (it.hasNext() && !exceededNumBlocksPerCheck()) { while (it.hasNext() && !exceededNumBlocksPerCheck() && namesystem
.isRunning()) {
numNodesChecked++; numNodesChecked++;
final Map.Entry<DatanodeDescriptor, AbstractList<BlockInfo>> final Map.Entry<DatanodeDescriptor, AbstractList<BlockInfo>>
entry = it.next(); entry = it.next();
@ -577,7 +583,28 @@ private void processBlocksForDecomInternal(
int decommissionOnlyReplicas = 0; int decommissionOnlyReplicas = 0;
int lowRedundancyInOpenFiles = 0; int lowRedundancyInOpenFiles = 0;
while (it.hasNext()) { while (it.hasNext()) {
if (insufficientList == null
&& numBlocksCheckedPerLock >= numBlocksPerCheck) {
// During fullscan insufficientlyReplicated will NOT be null, iterator
// will be DN's iterator. So should not yield lock, otherwise
// ConcurrentModificationException could occur.
// Once the fullscan done, iterator will be a copy. So can yield the
// lock.
// Yielding is required in case of block number is greater than the
// configured per-iteration-limit.
namesystem.writeUnlock();
try {
LOG.debug("Yielded lock during decommission check");
Thread.sleep(0, 500);
} catch (InterruptedException ignored) {
return;
}
// reset
numBlocksCheckedPerLock = 0;
namesystem.writeLock();
}
numBlocksChecked++; numBlocksChecked++;
numBlocksCheckedPerLock++;
final BlockInfo block = it.next(); final BlockInfo block = it.next();
// Remove the block from the list if it's no longer in the block map, // Remove the block from the list if it's no longer in the block map,
// e.g. the containing file has been deleted // e.g. the containing file has been deleted