|
@@ -181,12 +181,19 @@ public class Balancer {
|
|
|
+ "\n\t[-include [-f <hosts-file> | <comma-separated list of hosts>]]"
|
|
|
+ "\tIncludes only the specified datanodes."
|
|
|
+ "\n\t[-idleiterations <idleiterations>]"
|
|
|
- + "\tNumber of consecutive idle iterations (-1 for Infinite) before exit.";
|
|
|
-
|
|
|
+ + "\tNumber of consecutive idle iterations (-1 for Infinite) before "
|
|
|
+ + "exit."
|
|
|
+ + "\n\t[-runDuringUpgrade]"
|
|
|
+ + "\tWhether to run the balancer during an ongoing HDFS upgrade."
|
|
|
+ + "This is usually not desired since it will not affect used space "
|
|
|
+ + "on over-utilized machines.";
|
|
|
+
|
|
|
private final Dispatcher dispatcher;
|
|
|
+ private final NameNodeConnector nnc;
|
|
|
private final BalancingPolicy policy;
|
|
|
+ private final boolean runDuringUpgrade;
|
|
|
private final double threshold;
|
|
|
-
|
|
|
+
|
|
|
// all data node lists
|
|
|
private final Collection<Source> overUtilized = new LinkedList<Source>();
|
|
|
private final Collection<Source> aboveAvgUtilized = new LinkedList<Source>();
|
|
@@ -228,11 +235,13 @@ public class Balancer {
|
|
|
DFSConfigKeys.DFS_DATANODE_BALANCE_MAX_NUM_CONCURRENT_MOVES_KEY,
|
|
|
DFSConfigKeys.DFS_DATANODE_BALANCE_MAX_NUM_CONCURRENT_MOVES_DEFAULT);
|
|
|
|
|
|
+ this.nnc = theblockpool;
|
|
|
this.dispatcher = new Dispatcher(theblockpool, p.nodesToBeIncluded,
|
|
|
p.nodesToBeExcluded, movedWinWidth, moverThreads, dispatcherThreads,
|
|
|
maxConcurrentMovesPerNode, conf);
|
|
|
this.threshold = p.threshold;
|
|
|
this.policy = p.policy;
|
|
|
+ this.runDuringUpgrade = p.runDuringUpgrade;
|
|
|
}
|
|
|
|
|
|
private static long getCapacity(DatanodeStorageReport report, StorageType t) {
|
|
@@ -294,7 +303,7 @@ public class Balancer {
|
|
|
if (thresholdDiff <= 0) { // within threshold
|
|
|
aboveAvgUtilized.add(s);
|
|
|
} else {
|
|
|
- overLoadedBytes += precentage2bytes(thresholdDiff, capacity);
|
|
|
+ overLoadedBytes += percentage2bytes(thresholdDiff, capacity);
|
|
|
overUtilized.add(s);
|
|
|
}
|
|
|
g = s;
|
|
@@ -303,7 +312,7 @@ public class Balancer {
|
|
|
if (thresholdDiff <= 0) { // within threshold
|
|
|
belowAvgUtilized.add(g);
|
|
|
} else {
|
|
|
- underLoadedBytes += precentage2bytes(thresholdDiff, capacity);
|
|
|
+ underLoadedBytes += percentage2bytes(thresholdDiff, capacity);
|
|
|
underUtilized.add(g);
|
|
|
}
|
|
|
}
|
|
@@ -325,17 +334,17 @@ public class Balancer {
|
|
|
private static long computeMaxSize2Move(final long capacity, final long remaining,
|
|
|
final double utilizationDiff, final double threshold) {
|
|
|
final double diff = Math.min(threshold, Math.abs(utilizationDiff));
|
|
|
- long maxSizeToMove = precentage2bytes(diff, capacity);
|
|
|
+ long maxSizeToMove = percentage2bytes(diff, capacity);
|
|
|
if (utilizationDiff < 0) {
|
|
|
maxSizeToMove = Math.min(remaining, maxSizeToMove);
|
|
|
}
|
|
|
return Math.min(MAX_SIZE_TO_MOVE, maxSizeToMove);
|
|
|
}
|
|
|
|
|
|
- private static long precentage2bytes(double precentage, long capacity) {
|
|
|
- Preconditions.checkArgument(precentage >= 0,
|
|
|
- "precentage = " + precentage + " < 0");
|
|
|
- return (long)(precentage * capacity / 100.0);
|
|
|
+ private static long percentage2bytes(double percentage, long capacity) {
|
|
|
+ Preconditions.checkArgument(percentage >= 0, "percentage = %s < 0",
|
|
|
+ percentage);
|
|
|
+ return (long)(percentage * capacity / 100.0);
|
|
|
}
|
|
|
|
|
|
/* log the over utilized & under utilized nodes */
|
|
@@ -517,7 +526,13 @@ public class Balancer {
|
|
|
LOG.info( "Need to move "+ StringUtils.byteDesc(bytesLeftToMove)
|
|
|
+ " to make the cluster balanced." );
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ // Should not run the balancer during an unfinalized upgrade, since moved
|
|
|
+ // blocks are not deleted on the source datanode.
|
|
|
+ if (!runDuringUpgrade && nnc.isUpgrading()) {
|
|
|
+ return newResult(ExitStatus.UNFINALIZED_UPGRADE, bytesLeftToMove, -1);
|
|
|
+ }
|
|
|
+
|
|
|
/* Decide all the nodes that will participate in the block move and
|
|
|
* the number of bytes that need to be moved from one node to another
|
|
|
* in this iteration. Maximum bytes to be moved per node is
|
|
@@ -531,7 +546,7 @@ public class Balancer {
|
|
|
LOG.info( "Will move " + StringUtils.byteDesc(bytesBeingMoved) +
|
|
|
" in this iteration");
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/* For each pair of <source, target>, start a thread that repeatedly
|
|
|
* decide a block to be moved and its proxy source,
|
|
|
* then initiates the move until all bytes are moved or no more block
|
|
@@ -635,7 +650,8 @@ public class Balancer {
|
|
|
static final Parameters DEFAULT = new Parameters(
|
|
|
BalancingPolicy.Node.INSTANCE, 10.0,
|
|
|
NameNodeConnector.DEFAULT_MAX_IDLE_ITERATIONS,
|
|
|
- Collections.<String> emptySet(), Collections.<String> emptySet());
|
|
|
+ Collections.<String> emptySet(), Collections.<String> emptySet(),
|
|
|
+ false);
|
|
|
|
|
|
final BalancingPolicy policy;
|
|
|
final double threshold;
|
|
@@ -644,23 +660,34 @@ public class Balancer {
|
|
|
Set<String> nodesToBeExcluded;
|
|
|
//include only these nodes in balancing operations
|
|
|
Set<String> nodesToBeIncluded;
|
|
|
+ /**
|
|
|
+ * Whether to run the balancer during upgrade.
|
|
|
+ */
|
|
|
+ final boolean runDuringUpgrade;
|
|
|
|
|
|
Parameters(BalancingPolicy policy, double threshold, int maxIdleIteration,
|
|
|
- Set<String> nodesToBeExcluded, Set<String> nodesToBeIncluded) {
|
|
|
+ Set<String> nodesToBeExcluded, Set<String> nodesToBeIncluded,
|
|
|
+ boolean runDuringUpgrade) {
|
|
|
this.policy = policy;
|
|
|
this.threshold = threshold;
|
|
|
this.maxIdleIteration = maxIdleIteration;
|
|
|
this.nodesToBeExcluded = nodesToBeExcluded;
|
|
|
this.nodesToBeIncluded = nodesToBeIncluded;
|
|
|
+ this.runDuringUpgrade = runDuringUpgrade;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public String toString() {
|
|
|
- return Balancer.class.getSimpleName() + "." + getClass().getSimpleName()
|
|
|
- + "[" + policy + ", threshold=" + threshold +
|
|
|
- ", max idle iteration = " + maxIdleIteration +
|
|
|
- ", number of nodes to be excluded = "+ nodesToBeExcluded.size() +
|
|
|
- ", number of nodes to be included = "+ nodesToBeIncluded.size() +"]";
|
|
|
+ return String.format("%s.%s [%s,"
|
|
|
+ + " threshold = %s,"
|
|
|
+ + " max idle iteration = %s, "
|
|
|
+ + "number of nodes to be excluded = %s,"
|
|
|
+ + " number of nodes to be included = %s,"
|
|
|
+ + " run during upgrade = %s]",
|
|
|
+ Balancer.class.getSimpleName(), getClass().getSimpleName(),
|
|
|
+ policy, threshold, maxIdleIteration,
|
|
|
+ nodesToBeExcluded.size(), nodesToBeIncluded.size(),
|
|
|
+ runDuringUpgrade);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -702,6 +729,7 @@ public class Balancer {
|
|
|
int maxIdleIteration = Parameters.DEFAULT.maxIdleIteration;
|
|
|
Set<String> nodesTobeExcluded = Parameters.DEFAULT.nodesToBeExcluded;
|
|
|
Set<String> nodesTobeIncluded = Parameters.DEFAULT.nodesToBeIncluded;
|
|
|
+ boolean runDuringUpgrade = Parameters.DEFAULT.runDuringUpgrade;
|
|
|
|
|
|
if (args != null) {
|
|
|
try {
|
|
@@ -757,9 +785,16 @@ public class Balancer {
|
|
|
}
|
|
|
} else if ("-idleiterations".equalsIgnoreCase(args[i])) {
|
|
|
checkArgument(++i < args.length,
|
|
|
- "idleiterations value is missing: args = " + Arrays.toString(args));
|
|
|
+ "idleiterations value is missing: args = " + Arrays
|
|
|
+ .toString(args));
|
|
|
maxIdleIteration = Integer.parseInt(args[i]);
|
|
|
LOG.info("Using a idleiterations of " + maxIdleIteration);
|
|
|
+ } else if ("-runDuringUpgrade".equalsIgnoreCase(args[i])) {
|
|
|
+ runDuringUpgrade = true;
|
|
|
+ LOG.info("Will run the balancer even during an ongoing HDFS "
|
|
|
+ + "upgrade. Most users will not want to run the balancer "
|
|
|
+ + "during an upgrade since it will not affect used space "
|
|
|
+ + "on over-utilized machines.");
|
|
|
} else {
|
|
|
throw new IllegalArgumentException("args = "
|
|
|
+ Arrays.toString(args));
|
|
@@ -773,7 +808,8 @@ public class Balancer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return new Parameters(policy, threshold, maxIdleIteration, nodesTobeExcluded, nodesTobeIncluded);
|
|
|
+ return new Parameters(policy, threshold, maxIdleIteration,
|
|
|
+ nodesTobeExcluded, nodesTobeIncluded, runDuringUpgrade);
|
|
|
}
|
|
|
|
|
|
private static void printUsage(PrintStream out) {
|