Index: src/main/java/org/apache/hadoop/hbase/master/DefaultLoadBalancer.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/master/DefaultLoadBalancer.java (revision 1403005) +++ src/main/java/org/apache/hadoop/hbase/master/DefaultLoadBalancer.java (working copy) @@ -229,12 +229,14 @@ NavigableMap> serversByLoad = new TreeMap>(); int numRegions = 0; + int maxRegionCountPerServer = 0; // Iterate so we can count regions as we build the map for (Map.Entry> server: clusterState.entrySet()) { List regions = server.getValue(); int sz = regions.size(); if (sz == 0) emptyRegionServerPresent = true; numRegions += sz; + if (maxRegionCountPerServer < sz) maxRegionCountPerServer = sz; serversByLoad.put(new ServerAndLoad(server.getKey(), sz), regions); } // Check if we even need to do any load balancing @@ -254,6 +256,7 @@ } int min = numRegions / numServers; int max = numRegions % numServers == 0 ? min : min + 1; + if (maxRegionCountPerServer == 1) return null; // table is balanced // Using to check balance result. StringBuilder strBalanceParam = new StringBuilder(); @@ -315,13 +318,21 @@ fetchFromTail = false; Map underloadedServers = new HashMap(); + int maxToTake = numRegions - (int)average; for (Map.Entry> server: serversByLoad.entrySet()) { + if (maxToTake == 0) break; // no more to take int regionCount = server.getKey().getLoad(); - if (regionCount >= min) { - break; + if (regionCount >= min && regionCount > 0) { + continue; // look for other servers which haven't reached min } - underloadedServers.put(server.getKey().getServerName(), min - regionCount); + int regionsToPut = min - regionCount; + if (regionsToPut == 0) + { + regionsToPut = 1; + maxToTake--; + } + underloadedServers.put(server.getKey().getServerName(), regionsToPut); } // number of servers that get new regions int serversUnderloaded = underloadedServers.size();