From 332a61fd74fd2a9874319232c583ab5d2c53ff03 Mon Sep 17 00:00:00 2001 From: Kihwal Lee Date: Thu, 13 Oct 2016 13:52:49 -0500 Subject: [PATCH] HDFS-10987. Make Decommission less expensive when lot of blocks present. Contributed by Brahma Reddy Battula. --- .../blockmanagement/DecommissionManager.java | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DecommissionManager.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DecommissionManager.java index 6436fabd16..87b36da0b1 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DecommissionManager.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DecommissionManager.java @@ -388,6 +388,10 @@ private class Monitor implements Runnable { * The number of blocks that have been checked on this tick. */ 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 * statistics. @@ -418,6 +422,7 @@ public void run() { } // Reset the checked count at beginning of each iteration numBlocksChecked = 0; + numBlocksCheckedPerLock = 0; numNodesChecked = 0; // Check decom progress namesystem.writeLock(); @@ -451,7 +456,8 @@ private void check() { iterkey).iterator(); final LinkedList toRemove = new LinkedList<>(); - while (it.hasNext() && !exceededNumBlocksPerCheck()) { + while (it.hasNext() && !exceededNumBlocksPerCheck() && namesystem + .isRunning()) { numNodesChecked++; final Map.Entry> entry = it.next(); @@ -577,7 +583,28 @@ private void processBlocksForDecomInternal( int decommissionOnlyReplicas = 0; int lowRedundancyInOpenFiles = 0; 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++; + numBlocksCheckedPerLock++; final BlockInfo block = it.next(); // Remove the block from the list if it's no longer in the block map, // e.g. the containing file has been deleted