LOG.info("excluded nodes = " + p.getExcludedNodes()); LOG.info("source nodes = " + p.getSourceNodes()); checkKeytabAndInit(conf); System.out.println("Time Stamp Iteration# Bytes Already Moved Bytes Left To Move Bytes Being Moved"); if (p.getBlockPools().size() == 0 || p.getBlockPools().contains(nnc.getBlockpoolID())) { final Balancer b = new Balancer(nnc, p, conf); final Result r = b.runOneIteration(); r.print(iteration, System.out); b.resetData(conf); if (r.exitStatus == ExitStatus.IN_PROGRESS) { done = false;
/** * Parse arguments and then run Balancer. * * @param args command specific arguments. * @return exit code. 0 indicates success, non-zero indicates failure. */ @Override public int run(String[] args) { final long startTime = Time.monotonicNow(); final Configuration conf = getConf(); try { checkReplicationPolicyCompatibility(conf); final Collection<URI> namenodes = DFSUtil.getInternalNsRpcUris(conf); return Balancer.run(namenodes, parse(args), conf); } catch (IOException e) { System.out.println(e + ". Exiting ..."); return ExitStatus.IO_EXCEPTION.getExitCode(); } catch (InterruptedException e) { System.out.println(e + ". Exiting ..."); return ExitStatus.INTERRUPTED.getExitCode(); } finally { System.out.format("%-24s ", DateFormat.getDateTimeInstance().format(new Date())); System.out.println("Balancing took " + time2Str(Time.monotonicNow() - startTime)); } }
try { final List<DatanodeStorageReport> reports = dispatcher.init(); final long bytesLeftToMove = init(reports); if (bytesLeftToMove == 0) { System.out.println("The cluster is balanced. Exiting..."); return newResult(ExitStatus.SUCCESS, bytesLeftToMove, 0); } else { LOG.info( "Need to move "+ StringUtils.byteDesc(bytesLeftToMove) LOG.error("Balancer exiting as upgrade is not finalized, " + "please finalize the HDFS upgrade before running the balancer."); return newResult(ExitStatus.UNFINALIZED_UPGRADE, bytesLeftToMove, -1); final long bytesBeingMoved = chooseStorageGroups(); if (bytesBeingMoved == 0) { System.out.println("No block can be moved. Exiting..."); return newResult(ExitStatus.NO_MOVE_BLOCK, bytesLeftToMove, bytesBeingMoved); } else { LOG.info( "Will move " + StringUtils.byteDesc(bytesBeingMoved) + return newResult(ExitStatus.NO_MOVE_PROGRESS, bytesLeftToMove, bytesBeingMoved); return newResult(ExitStatus.IN_PROGRESS, bytesLeftToMove, bytesBeingMoved); } catch (IllegalArgumentException e) { System.out.println(e + ". Exiting ..."); return newResult(ExitStatus.ILLEGAL_ARGUMENTS); } catch (IOException e) { System.out.println(e + ". Exiting ..."); return newResult(ExitStatus.IO_EXCEPTION);
/** * For the given datanode, choose a candidate and then schedule it. * @return true if a candidate is chosen; false if no candidates is chosen. */ private <C extends StorageGroup> boolean choose4One(StorageGroup g, Collection<C> candidates, Matcher matcher) { final Iterator<C> i = candidates.iterator(); final C chosen = chooseCandidate(g, i, matcher); if (chosen == null) { return false; } if (g instanceof Source) { matchSourceWithTargetToMove((Source)g, chosen); } else { matchSourceWithTargetToMove((Source)chosen, g); } if (!chosen.hasSpaceForScheduling()) { i.remove(); } return true; }
final long capacity = getCapacity(r, t); final double thresholdDiff = Math.abs(utilizationDiff) - threshold; final long maxSize2Move = computeMaxSize2Move(capacity, getRemaining(r, t), utilizationDiff, maxSizeToMove); aboveAvgUtilized.add(s); } else { overLoadedBytes += percentage2bytes(thresholdDiff, capacity); overUtilized.add(s); belowAvgUtilized.add(g); } else { underLoadedBytes += percentage2bytes(thresholdDiff, capacity); underUtilized.add(g); logUtilizationCollections();
for(InetSocketAddress isa : namenodes) { try{ Balancer b = new Balancer(conf); b.init(isa); balancers.add(b); } catch (IOException e) { while (iter.hasNext()) { Balancer b = iter.next(); b.resetData(); final int r = b.run(iterations, formatter); if (r == IN_PROGRESS) { done = false; } else if (r != SUCCESS) { b.close(); LOG.info("Namenode " + b.namenodeAddress + " balancing exits..."); iter.remove(); b.close();
try { init(parseArgs(args)); out = checkAndMarkRunningBalancer(); if (out == null) { System.out.println("Another balancer is running. Exiting..."); long bytesLeftToMove = initNodes(); if (bytesLeftToMove == 0) { System.out.println("The cluster is balanced. Exiting..."); long bytesToMove = chooseNodes(); if (bytesToMove == 0) { System.out.println("No block can be moved. Exiting..."); if (dispatchBlockMoves() > 0) { notChangedIterations = 0; } else { resetData(); time2Str(Util.now()-startTime));
private void runBalancerDefaultConstructor(Configuration conf, long totalUsedSpace, long totalCapacity) throws Exception { waitForHeartBeat(totalUsedSpace, totalCapacity); // start rebalancing balancer = new Balancer(); balancer.setConf(conf); balancer.run(new String[0]); waitForHeartBeat(totalUsedSpace, totalCapacity); boolean balanced; do { DatanodeInfo[] datanodeReport = client .getDatanodeReport(DatanodeReportType.ALL); assertEquals(datanodeReport.length, cluster.getDataNodes().size()); balanced = true; double avgUtilization = ((double) totalUsedSpace) / totalCapacity * 100; for (DatanodeInfo datanode : datanodeReport) { if (Math.abs(avgUtilization - ((double) datanode.getDfsUsed()) / datanode.getCapacity() * 100) > 10) { balanced = false; try { Thread.sleep(100); } catch (InterruptedException ignored) { } break; } } } while (!balanced); }
shuffleArray(datanodes); for (DatanodeInfo datanode : datanodes) { if (datanode.isDecommissioned() || datanode.isDecommissionInProgress()) { if (getRemaining(datanode) < avgRemaining) { datanodeS = new Source(datanode, avgRemaining, threshold); if (isAboveAvgUtilized(datanodeS)) { this.aboveAvgUtilizedDatanodes.add((Source)datanodeS); } else { assert(isOverUtilized(datanodeS)) : datanodeS.getName()+ "is not an overUtilized node"; this.overUtilizedDatanodes.add((Source)datanodeS); if ( isBelowAvgUtilized(datanodeS)) { this.belowAvgUtilizedDatanodes.add(datanodeS); } else { assert (isUnderUtilized(datanodeS)) : datanodeS.getName()+ "is not an underUtilized node"; this.underUtilizedDatanodes.add(datanodeS); logImbalancedNodes();
Collections.shuffle(connectors); for(NameNodeConnector nnc : connectors) { final Balancer b = new Balancer(nnc, p, conf); final Result r = b.runOneIteration(); r.print(iteration, System.out); b.resetData(conf); if (r.exitStatus == ExitStatus.IN_PROGRESS) { done = false;
private void runBalancer(Configuration conf, long totalUsedSpace, long totalCapacity ) throws Exception { waitForHeartBeat(totalUsedSpace, totalCapacity); // start rebalancing balancer = new Balancer(conf); balancer.run(new String[0]); waitForHeartBeat(totalUsedSpace, totalCapacity); boolean balanced; do { DatanodeInfo[] datanodeReport = client.getDatanodeReport(DatanodeReportType.ALL); assertEquals(datanodeReport.length, cluster.getDataNodes().size()); balanced = true; double avgUtilization = ((double)totalUsedSpace)/totalCapacity*100; for(DatanodeInfo datanode:datanodeReport) { if(Math.abs(avgUtilization- ((double)datanode.getDfsUsed())/datanode.getCapacity()*100)>10) { balanced = false; try { Thread.sleep(100); } catch(InterruptedException ignored) { } break; } } } while(!balanced); }
long bytesLeftToMove = initNodes(); if (bytesLeftToMove == 0) { System.out.println("The cluster is balanced. Exiting..."); final long bytesToMove = chooseNodes(); if (bytesToMove == 0) { System.out.println("No block can be moved. Exiting..."); if (dispatchBlockMoves() > 0) { notChangedIterations = 0; } else { resetData();
public int run(String[] args) throws Exception { final long startTime = Util.now(); try { checkReplicationPolicyCompatibility(conf); final List<InetSocketAddress> namenodes = DFSUtil.getClientRpcAddresses(conf, null); parse(args); return Balancer.run(namenodes, conf); } catch (IOException e) { System.out.println(e + ". Exiting ..."); return IO_EXCEPTION; } catch (InterruptedException e) { System.out.println(e + ". Exiting ..."); return INTERRUPTED; } catch (Exception e) { e.printStackTrace(); return ILLEGAL_ARGS; } finally { System.out.println("Balancing took " + time2Str(Util.now()-startTime)); } }
/** * Run a balancer * @param args */ public static void main(String[] args) { try { System.exit( ToolRunner.run(null, new Balancer(), args) ); } catch (Throwable e) { LOG.error(StringUtils.stringifyException(e)); System.exit(-1); } }
/** Decide all <source, target> pairs according to the matcher. */ private void chooseStorageGroups(final Matcher matcher) { /* first step: match each overUtilized datanode (source) to * one or more underUtilized datanodes (targets). */ LOG.info("chooseStorageGroups for " + matcher + ": overUtilized => underUtilized"); chooseStorageGroups(overUtilized, underUtilized, matcher); /* match each remaining overutilized datanode (source) to * below average utilized datanodes (targets). * Note only overutilized datanodes that haven't had that max bytes to move * satisfied in step 1 are selected */ LOG.info("chooseStorageGroups for " + matcher + ": overUtilized => belowAvgUtilized"); chooseStorageGroups(overUtilized, belowAvgUtilized, matcher); /* match each remaining underutilized datanode (target) to * above average utilized datanodes (source). * Note only underutilized datanodes that have not had that max bytes to * move satisfied in step 1 are selected. */ LOG.info("chooseStorageGroups for " + matcher + ": underUtilized => aboveAvgUtilized"); chooseStorageGroups(underUtilized, aboveAvgUtilized, matcher); }
/** * For each datanode, choose matching nodes from the candidates. Either the * datanodes or the candidates are source nodes with (utilization > Avg), and * the others are target nodes with (utilization < Avg). */ private <G extends StorageGroup, C extends StorageGroup> void chooseStorageGroups(Collection<G> groups, Collection<C> candidates, Matcher matcher) { for(final Iterator<G> i = groups.iterator(); i.hasNext();) { final G g = i.next(); for(; choose4One(g, candidates, matcher); ); if (!g.hasSpaceForScheduling()) { i.remove(); } } }
final long capacity = getCapacity(r, t); final double utilizationDiff = utilization - policy.getAvgUtilization(t); final double thresholdDiff = Math.abs(utilizationDiff) - threshold; final long maxSize2Move = computeMaxSize2Move(capacity, getRemaining(r, t), utilizationDiff, threshold, maxSizeToMove); aboveAvgUtilized.add(s); } else { overLoadedBytes += percentage2bytes(thresholdDiff, capacity); overUtilized.add(s); belowAvgUtilized.add(g); } else { underLoadedBytes += percentage2bytes(thresholdDiff, capacity); underUtilized.add(g); logUtilizationCollections();
/** * For the given datanode, choose a candidate and then schedule it. * @return true if a candidate is chosen; false if no candidates is chosen. */ private <C extends StorageGroup> boolean choose4One(StorageGroup g, Collection<C> candidates, Matcher matcher) { final Iterator<C> i = candidates.iterator(); final C chosen = chooseCandidate(g, i, matcher); if (chosen == null) { return false; } if (g instanceof Source) { matchSourceWithTargetToMove((Source)g, chosen); } else { matchSourceWithTargetToMove((Source)chosen, g); } if (!chosen.hasSpaceForScheduling()) { i.remove(); } return true; }
/** * Run a balancer * @param args */ public static void main(String[] args) { try { System.exit( ToolRunner.run(null, new Balancer(), args) ); } catch (Throwable e) { LOG.error(StringUtils.stringifyException(e)); System.exit(-1); } }
/** * Decide all <source, target> pairs and * the number of bytes to move from a source to a target * Maximum bytes to be moved per storage group is * min(1 Band worth of bytes, MAX_SIZE_TO_MOVE). * @return total number of bytes to move in this iteration */ private long chooseStorageGroups() { // First, match nodes on the same node group if cluster is node group aware if (dispatcher.getCluster().isNodeGroupAware()) { chooseStorageGroups(Matcher.SAME_NODE_GROUP); } // Then, match nodes on the same rack chooseStorageGroups(Matcher.SAME_RACK); // At last, match all remaining nodes chooseStorageGroups(Matcher.ANY_OTHER); return dispatcher.bytesToMove(); }