-
Notifications
You must be signed in to change notification settings - Fork 8.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HDFS-17646. Add Option to limit Balancer overUtilized nodes num in each iteration. #7120
Changes from all commits
574a32a
508cd62
fce6a4f
6d8a46c
665e9b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -208,6 +208,8 @@ public class Balancer { | |
+ "\n\t[-sortTopNodes]" | ||
+ "\tSort datanodes based on the utilization so " | ||
+ "that highly utilized datanodes get scheduled first." | ||
+ "\n\t[-limitOverUtilizedNum <specified maximum number of overUtilized datanodes>]" | ||
+ "\tLimit the maximum number of overUtilized datanodes." | ||
+ "\n\t[-hotBlockTimeInterval]\tprefer to move cold blocks."; | ||
|
||
@VisibleForTesting | ||
|
@@ -227,6 +229,7 @@ public class Balancer { | |
private final long maxSizeToMove; | ||
private final long defaultBlockSize; | ||
private final boolean sortTopNodes; | ||
private final int limitOverUtilizedNum; | ||
private final BalancerMetrics metrics; | ||
|
||
// all data node lists | ||
|
@@ -352,6 +355,7 @@ static int getFailedTimesSinceLastSuccessfulBalance() { | |
this.sourceNodes = p.getSourceNodes(); | ||
this.runDuringUpgrade = p.getRunDuringUpgrade(); | ||
this.sortTopNodes = p.getSortTopNodes(); | ||
this.limitOverUtilizedNum = p.getLimitOverUtilizedNum(); | ||
|
||
this.maxSizeToMove = getLongBytes(conf, | ||
DFSConfigKeys.DFS_BALANCER_MAX_SIZE_TO_MOVE_KEY, | ||
|
@@ -456,11 +460,18 @@ private long init(List<DatanodeStorageReport> reports) { | |
sortOverUtilized(overUtilizedPercentage); | ||
} | ||
|
||
// Limit the maximum number of overUtilized datanodes | ||
// If excludedOverUtilizedNum is greater than 0, The overUtilized nodes num is limited | ||
int excludedOverUtilizedNum = Math.max(overUtilized.size() - limitOverUtilizedNum, 0); | ||
if (excludedOverUtilizedNum > 0) { | ||
limitOverUtilizedNum(); | ||
} | ||
|
||
logUtilizationCollections(); | ||
metrics.setNumOfOverUtilizedNodes(overUtilized.size()); | ||
metrics.setNumOfUnderUtilizedNodes(underUtilized.size()); | ||
|
||
Preconditions.checkState(dispatcher.getStorageGroupMap().size() | ||
Preconditions.checkState(dispatcher.getStorageGroupMap().size() - excludedOverUtilizedNum | ||
== overUtilized.size() + underUtilized.size() + aboveAvgUtilized.size() | ||
+ belowAvgUtilized.size(), | ||
"Mismatched number of storage groups"); | ||
|
@@ -484,6 +495,20 @@ private void sortOverUtilized(Map<Source, Double> overUtilizedPercentage) { | |
); | ||
} | ||
|
||
private void limitOverUtilizedNum() { | ||
Preconditions.checkState(overUtilized instanceof LinkedList, | ||
"Collection overUtilized is not a LinkedList."); | ||
LinkedList<Source> list = (LinkedList<Source>) overUtilized; | ||
|
||
LOG.info("Limiting over-utilized nodes num, if using the '-sortTopNodes' param," + | ||
" the overUtilized nodes of top will be retained"); | ||
|
||
int size = overUtilized.size(); | ||
for (int i = 0; i < size - limitOverUtilizedNum; i++) { | ||
list.removeLast(); | ||
} | ||
} | ||
|
||
private static long computeMaxSize2Move(final long capacity, final long remaining, | ||
final double utilizationDiff, final long max) { | ||
final double diff = Math.abs(utilizationDiff); | ||
|
@@ -1071,6 +1096,14 @@ static BalancerParameters parse(String[] args) { | |
b.setSortTopNodes(true); | ||
LOG.info("Balancer will sort nodes by" + | ||
" capacity usage percentage to prioritize top used nodes"); | ||
} else if ("-limitOverUtilizedNum".equalsIgnoreCase(args[i])) { | ||
Preconditions.checkArgument(++i < args.length, | ||
"limitOverUtilizedNum value is missing: args = " + Arrays.toString(args)); | ||
int limitNum = Integer.parseInt(args[i]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we need to check if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed, 0 is legal, non-negative numbers are okay. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now, restricting the list that is greater than the threshold, and in the future, we will also need to restrict the list that is greater than the average (aboveAvgUtilized), 0 is legal. |
||
Preconditions.checkArgument(limitNum >= 0, | ||
"limitOverUtilizedNum must be non-negative"); | ||
LOG.info("Using a limitOverUtilizedNum of {}", limitNum); | ||
b.setLimitOverUtilizedNum(limitNum); | ||
} else { | ||
throw new IllegalArgumentException("args = " | ||
+ Arrays.toString(args)); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just suggest to add another one separate function rather than located here which is
sort
something.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix