getFavoredNodes(RegionInfo region) {
return favoredNodesMap.get(region.getRegionNameAsString());
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java
similarity index 86%
rename from hbase-server/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java
rename to hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java
index b49ca824236a..491b5fabe42a 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java
+++ b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java
@@ -30,21 +30,19 @@
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.conf.ConfigurationObserver;
+import org.apache.hadoop.hbase.master.balancer.ClusterInfoProvider;
import org.apache.yetus.audience.InterfaceAudience;
/**
- * Makes decisions about the placement and movement of Regions across
- * RegionServers.
- *
- * Cluster-wide load balancing will occur only when there are no regions in
- * transition and according to a fixed period of a time using {@link #balanceCluster(Map)}.
- *
- *
On cluster startup, bulk assignment can be used to determine
- * locations for all Regions in a cluster.
- *
- *
This class produces plans for the
- * {@link org.apache.hadoop.hbase.master.assignment.AssignmentManager}
- * to execute.
+ * Makes decisions about the placement and movement of Regions across RegionServers.
+ *
+ * Cluster-wide load balancing will occur only when there are no regions in transition and according
+ * to a fixed period of a time using {@link #balanceCluster(Map)}.
+ *
+ * On cluster startup, bulk assignment can be used to determine locations for all Regions in a
+ * cluster.
+ *
+ * This class produces plans for the {@code AssignmentManager} to execute.
*/
@InterfaceAudience.Private
public interface LoadBalancer extends Configurable, Stoppable, ConfigurationObserver {
@@ -69,15 +67,14 @@ public interface LoadBalancer extends Configurable, Stoppable, ConfigurationObse
/**
- * Set the master service.
+ * Set the cluster info provider. Usually it is just a wrapper of master.
*/
- void setMasterServices(MasterServices masterServices);
+ void setClusterInfoProvider(ClusterInfoProvider provider);
/**
* Perform the major balance operation for cluster, will invoke {@link #balanceTable} to do actual
- * balance. Normally not need override this method, except
- * {@link org.apache.hadoop.hbase.master.balancer.SimpleLoadBalancer} and
- * {@link org.apache.hadoop.hbase.rsgroup.RSGroupBasedLoadBalancer}
+ * balance. Normally not need override this method, except {@link SimpleLoadBalancer} and
+ * {@code RSGroupBasedLoadBalancer}
* @param loadOfAllTable region load of servers for all table
* @return a list of regions to be moved, including source and destination, or null if cluster is
* already balanced
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java
similarity index 91%
rename from hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java
rename to hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java
index ad751adaa36b..2dcf77b955d1 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java
+++ b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java
@@ -30,18 +30,14 @@
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ThreadLocalRandom;
-import java.util.function.Predicate;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.ClusterMetrics;
import org.apache.hadoop.hbase.HBaseIOException;
import org.apache.hadoop.hbase.HConstants;
-import org.apache.hadoop.hbase.ServerMetrics;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.RegionInfo;
-import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.master.LoadBalancer;
-import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.RackManager;
import org.apache.hadoop.hbase.master.RegionPlan;
import org.apache.yetus.audience.InterfaceAudience;
@@ -55,10 +51,8 @@
/**
* The base class for load balancers. It provides the the functions used to by
- * {@link org.apache.hadoop.hbase.master.assignment.AssignmentManager} to assign regions
- * in the edge cases. It doesn't provide an implementation of the
- * actual balancing algorithm.
- *
+ * {@code AssignmentManager} to assign regions in the edge cases. It doesn't provide an
+ * implementation of the actual balancing algorithm.
*/
@InterfaceAudience.Private
public abstract class BaseLoadBalancer implements LoadBalancer {
@@ -72,9 +66,6 @@ public abstract class BaseLoadBalancer implements LoadBalancer {
protected static final int MIN_SERVER_BALANCE = 2;
private volatile boolean stopped = false;
- private static final Predicate IDLE_SERVER_PREDICATOR
- = load -> load.getRegionMetrics().isEmpty();
-
protected RegionHDFSBlockLocationFinder regionFinder;
protected boolean useRegionFinder;
protected boolean isByTable = false;
@@ -88,7 +79,8 @@ public abstract class BaseLoadBalancer implements LoadBalancer {
protected MetricsBalancer metricsBalancer = null;
protected ClusterMetrics clusterStatus = null;
protected ServerName masterServerName;
- protected MasterServices services;
+ protected ClusterInfoProvider provider;
+
/**
* The constructor that uses the basic MetricsBalancer
*/
@@ -151,24 +143,17 @@ public synchronized void setClusterMetrics(ClusterMetrics st) {
@Override
- public void setMasterServices(MasterServices masterServices) {
- masterServerName = masterServices.getServerName();
- this.services = masterServices;
+ public void setClusterInfoProvider(ClusterInfoProvider provider) {
+ this.provider = provider;
if (useRegionFinder) {
- this.regionFinder.setClusterInfoProvider(new MasterClusterInfoProvider(services));
+ this.regionFinder.setClusterInfoProvider(provider);
}
}
@Override
public void postMasterStartupInitialize() {
- if (services != null && regionFinder != null) {
- try {
- Set regions =
- services.getAssignmentManager().getRegionStates().getRegionAssignments().keySet();
- regionFinder.refreshAndWait(regions);
- } catch (Exception e) {
- LOG.warn("Refreshing region HDFS Block dist failed with exception, ignoring", e);
- }
+ if (provider != null && regionFinder != null) {
+ regionFinder.refreshAndWait(provider.getAssignedRegions());
}
}
@@ -277,22 +262,15 @@ public Map> roundRobinAssignment(List r
BalancerClusterState cluster = createCluster(servers, regions);
Map> assignments = new HashMap<>();
roundRobinAssignment(cluster, regions, servers, assignments);
- return assignments;
+ return Collections.unmodifiableMap(assignments);
}
private BalancerClusterState createCluster(List servers,
Collection regions) throws HBaseIOException {
- boolean hasRegionReplica = false;
+ boolean hasRegionReplica= false;
try {
- if (services != null && services.getTableDescriptors() != null) {
- Map tds = services.getTableDescriptors().getAll();
- for (RegionInfo regionInfo : regions) {
- TableDescriptor td = tds.get(regionInfo.getTable().getNameWithNamespaceInclAsString());
- if (td != null && td.getRegionReplication() > 1) {
- hasRegionReplica = true;
- break;
- }
- }
+ if (provider != null) {
+ hasRegionReplica = provider.hasRegionReplica(regions);
}
} catch (IOException ioe) {
throw new HBaseIOException(ioe);
@@ -320,8 +298,8 @@ private BalancerClusterState createCluster(List servers,
}
private List findIdleServers(List servers) {
- return this.services.getServerManager()
- .getOnlineServersListWithPredicator(servers, IDLE_SERVER_PREDICATOR);
+ return provider.getOnlineServersListWithPredicator(servers,
+ metrics -> metrics.getRegionMetrics().isEmpty());
}
/**
@@ -474,7 +452,7 @@ public Map> retainAssignment(Map
}
}
- private Map> getRegionAssignmentsByServer(
- Collection regions) {
- if (this.services != null && this.services.getAssignmentManager() != null) {
- return this.services.getAssignmentManager().getSnapShotOfAssignment(regions);
- } else {
- return new HashMap<>();
- }
+ // return a modifiable map, as we may add more entries into the returned map.
+ private Map>
+ getRegionAssignmentsByServer(Collection regions) {
+ return provider != null ? new HashMap<>(provider.getSnapShotOfAssignment(regions)) :
+ new HashMap<>();
}
private Map> toEnsumbleTableLoad(
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/CandidateGenerator.java b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/CandidateGenerator.java
similarity index 92%
rename from hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/CandidateGenerator.java
rename to hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/CandidateGenerator.java
index cf43269eb45b..faaaff9733c8 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/CandidateGenerator.java
+++ b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/CandidateGenerator.java
@@ -35,16 +35,12 @@ abstract class CandidateGenerator {
* From a list of regions pick a random one. Null can be returned which
* {@link StochasticLoadBalancer#balanceCluster(Map)} recognize as signal to try a region move
* rather than swap.
- *
* @param cluster The state of the cluster
* @param server index of the server
- * @param chanceOfNoSwap Chance that this will decide to try a move rather
- * than a swap.
- * @return a random {@link RegionInfo} or null if an asymmetrical move is
- * suggested.
+ * @param chanceOfNoSwap Chance that this will decide to try a move rather than a swap.
+ * @return a random {@link RegionInfo} or null if an asymmetrical move is suggested.
*/
- int pickRandomRegion(BalancerClusterState cluster, int server,
- double chanceOfNoSwap) {
+ int pickRandomRegion(BalancerClusterState cluster, int server, double chanceOfNoSwap) {
// Check to see if this is just a move.
if (cluster.regionsPerServer[server].length == 0
|| ThreadLocalRandom.current().nextFloat() < chanceOfNoSwap) {
@@ -95,8 +91,7 @@ int pickOtherRandomRack(BalancerClusterState cluster, int rackIndex) {
}
}
- BalanceAction pickRandomRegions(BalancerClusterState cluster,
- int thisServer, int otherServer) {
+ BalanceAction pickRandomRegions(BalancerClusterState cluster, int thisServer, int otherServer) {
if (thisServer < 0 || otherServer < 0) {
return BalanceAction.NULL_ACTION;
}
@@ -115,14 +110,12 @@ BalanceAction pickRandomRegions(BalancerClusterState cluster,
return getAction(thisServer, thisRegion, otherServer, otherRegion);
}
- protected BalanceAction getAction(int fromServer, int fromRegion,
- int toServer, int toRegion) {
+ protected BalanceAction getAction(int fromServer, int fromRegion, int toServer, int toRegion) {
if (fromServer < 0 || toServer < 0) {
return BalanceAction.NULL_ACTION;
}
if (fromRegion >= 0 && toRegion >= 0) {
- return new SwapRegionsAction(fromServer, fromRegion,
- toServer, toRegion);
+ return new SwapRegionsAction(fromServer, fromRegion, toServer, toRegion);
} else if (fromRegion >= 0) {
return new MoveRegionAction(fromRegion, fromServer, toServer);
} else if (toRegion >= 0) {
diff --git a/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/ClusterInfoProvider.java b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/ClusterInfoProvider.java
index 47247b144e0a..0686cf8a0df7 100644
--- a/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/ClusterInfoProvider.java
+++ b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/ClusterInfoProvider.java
@@ -18,9 +18,14 @@
package org.apache.hadoop.hbase.master.balancer;
import java.io.IOException;
+import java.util.Collection;
import java.util.List;
+import java.util.Map;
+import java.util.function.Predicate;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HDFSBlocksDistribution;
+import org.apache.hadoop.hbase.ServerMetrics;
+import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.TableDescriptor;
@@ -45,6 +50,11 @@ public interface ClusterInfoProvider {
*/
TableDescriptor getTableDescriptor(TableName tableName) throws IOException;
+ /**
+ * Returns the number of tables on this cluster.
+ */
+ int getNumberOfTables() throws IOException;
+
/**
* Compute the block distribution for the given region.
*
@@ -52,4 +62,20 @@ public interface ClusterInfoProvider {
*/
HDFSBlocksDistribution computeHDFSBlocksDistribution(Configuration conf,
TableDescriptor tableDescriptor, RegionInfo regionInfo) throws IOException;
+
+ /**
+ * Check whether we have region replicas enabled for the tables of the given regions.
+ */
+ boolean hasRegionReplica(Collection regions) throws IOException;
+
+ /**
+ * Returns a copy of the internal list of online servers matched by the given {@code filter}.
+ */
+ List getOnlineServersListWithPredicator(List servers,
+ Predicate filter);
+
+ /**
+ * Get a snapshot of the current assignment status.
+ */
+ Map> getSnapShotOfAssignment(Collection regions);
}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/LoadCandidateGenerator.java b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/LoadCandidateGenerator.java
similarity index 100%
rename from hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/LoadCandidateGenerator.java
rename to hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/LoadCandidateGenerator.java
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/LocalityBasedCandidateGenerator.java b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/LocalityBasedCandidateGenerator.java
similarity index 91%
rename from hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/LocalityBasedCandidateGenerator.java
rename to hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/LocalityBasedCandidateGenerator.java
index 9da884f40d0d..c8e56f193bf0 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/LocalityBasedCandidateGenerator.java
+++ b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/LocalityBasedCandidateGenerator.java
@@ -36,8 +36,8 @@ BalanceAction generate(BalancerClusterState cluster) {
int currentServer = cluster.regionIndexToServerIndex[region];
if (currentServer != cluster.getOrComputeRegionsToMostLocalEntities(
BalancerClusterState.LocalityType.SERVER)[region]) {
- Optional potential = tryMoveOrSwap(cluster,
- currentServer, region, cluster.getOrComputeRegionsToMostLocalEntities(
+ Optional potential = tryMoveOrSwap(cluster, currentServer, region,
+ cluster.getOrComputeRegionsToMostLocalEntities(
BalancerClusterState.LocalityType.SERVER)[region]);
if (potential.isPresent()) {
return potential.get();
@@ -48,16 +48,16 @@ BalanceAction generate(BalancerClusterState cluster) {
return BalanceAction.NULL_ACTION;
}
- private Optional tryMoveOrSwap(BalancerClusterState cluster,
- int fromServer, int fromRegion, int toServer) {
+ private Optional tryMoveOrSwap(BalancerClusterState cluster, int fromServer,
+ int fromRegion, int toServer) {
// Try move first. We know apriori fromRegion has the highest locality on toServer
if (cluster.serverHasTooFewRegions(toServer)) {
return Optional.of(getAction(fromServer, fromRegion, toServer, -1));
}
// Compare locality gain/loss from swapping fromRegion with regions on toServer
- double fromRegionLocalityDelta = getWeightedLocality(cluster, fromRegion, toServer)
- - getWeightedLocality(cluster, fromRegion, fromServer);
- int toServertotalRegions = cluster.regionsPerServer[toServer].length;
+ double fromRegionLocalityDelta = getWeightedLocality(cluster, fromRegion, toServer) -
+ getWeightedLocality(cluster, fromRegion, fromServer);
+ int toServertotalRegions = cluster.regionsPerServer[toServer].length;
if (toServertotalRegions > 0) {
int startIndex = ThreadLocalRandom.current().nextInt(toServertotalRegions);
for (int i = 0; i < toServertotalRegions; i++) {
diff --git a/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/RandomCandidateGenerator.java b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/RandomCandidateGenerator.java
new file mode 100644
index 000000000000..dad201152300
--- /dev/null
+++ b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/RandomCandidateGenerator.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.master.balancer;
+
+import org.apache.yetus.audience.InterfaceAudience;
+
+@InterfaceAudience.Private
+class RandomCandidateGenerator extends CandidateGenerator {
+
+ @Override
+ BalanceAction generate(BalancerClusterState cluster) {
+
+ int thisServer = pickRandomServer(cluster);
+
+ // Pick the other server
+ int otherServer = pickOtherRandomServer(cluster, thisServer);
+
+ return pickRandomRegions(cluster, thisServer, otherServer);
+ }
+}
\ No newline at end of file
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.java b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.java
similarity index 88%
rename from hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.java
rename to hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.java
index f3b69554acac..e14595088569 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.java
+++ b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.java
@@ -22,8 +22,8 @@
import org.apache.yetus.audience.InterfaceAudience;
/**
- * Generates candidates which moves the replicas out of the region server for
- * co-hosted region replicas
+ * Generates candidates which moves the replicas out of the region server for co-hosted region
+ * replicas
*/
@InterfaceAudience.Private
class RegionReplicaCandidateGenerator extends CandidateGenerator {
@@ -31,17 +31,16 @@ class RegionReplicaCandidateGenerator extends CandidateGenerator {
protected final RandomCandidateGenerator randomGenerator = new RandomCandidateGenerator();
/**
- * Randomly select one regionIndex out of all region replicas co-hosted in the same group
- * (a group is a server, host or rack)
- *
+ * Randomly select one regionIndex out of all region replicas co-hosted in the same group (a group
+ * is a server, host or rack)
* @param primariesOfRegionsPerGroup either Cluster.primariesOfRegionsPerServer,
- * primariesOfRegionsPerHost or primariesOfRegionsPerRack
+ * primariesOfRegionsPerHost or primariesOfRegionsPerRack
* @param regionsPerGroup either Cluster.regionsPerServer, regionsPerHost or regionsPerRack
* @param regionIndexToPrimaryIndex Cluster.regionsIndexToPrimaryIndex
* @return a regionIndex for the selected primary or -1 if there is no co-locating
*/
int selectCoHostedRegionPerGroup(int[] primariesOfRegionsPerGroup, int[] regionsPerGroup,
- int[] regionIndexToPrimaryIndex) {
+ int[] regionIndexToPrimaryIndex) {
int currentPrimary = -1;
int currentPrimaryIndex = -1;
int selectedPrimaryIndex = -1;
@@ -50,8 +49,7 @@ int selectCoHostedRegionPerGroup(int[] primariesOfRegionsPerGroup, int[] regions
// ids for the regions hosted in server, a consecutive repetition means that replicas
// are co-hosted
for (int j = 0; j <= primariesOfRegionsPerGroup.length; j++) {
- int primary = j < primariesOfRegionsPerGroup.length
- ? primariesOfRegionsPerGroup[j] : -1;
+ int primary = j < primariesOfRegionsPerGroup.length ? primariesOfRegionsPerGroup[j] : -1;
if (primary != currentPrimary) { // check for whether we see a new primary
int numReplicas = j - currentPrimaryIndex;
if (numReplicas > 1) { // means consecutive primaries, indicating co-location
@@ -89,10 +87,8 @@ BalanceAction generate(BalancerClusterState cluster) {
return BalanceAction.NULL_ACTION;
}
- int regionIndex = selectCoHostedRegionPerGroup(
- cluster.primariesOfRegionsPerServer[serverIndex],
- cluster.regionsPerServer[serverIndex],
- cluster.regionIndexToPrimaryIndex);
+ int regionIndex = selectCoHostedRegionPerGroup(cluster.primariesOfRegionsPerServer[serverIndex],
+ cluster.regionsPerServer[serverIndex], cluster.regionIndexToPrimaryIndex);
// if there are no pairs of region replicas co-hosted, default to random generator
if (regionIndex == -1) {
diff --git a/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCandidateGenerator.java b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCandidateGenerator.java
new file mode 100644
index 000000000000..cb00f8e08aac
--- /dev/null
+++ b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCandidateGenerator.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.master.balancer;
+
+import java.util.concurrent.ThreadLocalRandom;
+import org.apache.yetus.audience.InterfaceAudience;
+
+/**
+ * Generates candidates which moves the replicas out of the rack for co-hosted region replicas in
+ * the same rack
+ */
+@InterfaceAudience.Private
+class RegionReplicaRackCandidateGenerator extends RegionReplicaCandidateGenerator {
+ @Override
+ BalanceAction generate(BalancerClusterState cluster) {
+ int rackIndex = pickRandomRack(cluster);
+ if (cluster.numRacks <= 1 || rackIndex == -1) {
+ return super.generate(cluster);
+ }
+
+ int regionIndex = selectCoHostedRegionPerGroup(cluster.primariesOfRegionsPerRack[rackIndex],
+ cluster.regionsPerRack[rackIndex], cluster.regionIndexToPrimaryIndex);
+
+ // if there are no pairs of region replicas co-hosted, default to random generator
+ if (regionIndex == -1) {
+ // default to randompicker
+ return randomGenerator.generate(cluster);
+ }
+
+ int serverIndex = cluster.regionIndexToServerIndex[regionIndex];
+ int toRackIndex = pickOtherRandomRack(cluster, rackIndex);
+
+ int rand = ThreadLocalRandom.current().nextInt(cluster.serversPerRack[toRackIndex].length);
+ int toServerIndex = cluster.serversPerRack[toRackIndex][rand];
+ int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);
+ return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);
+ }
+}
\ No newline at end of file
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/SimpleLoadBalancer.java b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/SimpleLoadBalancer.java
similarity index 99%
rename from hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/SimpleLoadBalancer.java
rename to hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/SimpleLoadBalancer.java
index 2c5947b4644a..a8b161a98a1a 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/SimpleLoadBalancer.java
+++ b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/balancer/SimpleLoadBalancer.java
@@ -48,8 +48,7 @@
* On cluster startup, bulk assignment can be used to determine locations for all Regions in a
* cluster.
*
- * This classes produces plans for the
- * {@link org.apache.hadoop.hbase.master.assignment.AssignmentManager} to execute.
+ * This classes produces plans for the {@code AssignmentManager} to execute.
*/
@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)
public class SimpleLoadBalancer extends BaseLoadBalancer {
@@ -313,7 +312,7 @@ public List balanceTable(TableName tableName,
}
}
serverBalanceInfo.put(sal.getServerName(),
- new BalanceInfo(numToOffload, (-1)*numTaken, server.getValue()));
+ new BalanceInfo(numToOffload, -numTaken, server.getValue()));
}
int totalNumMoved = regionsToMove.size();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/BalancerTestBase.java b/hbase-balancer/src/test/java/org/apache/hadoop/hbase/master/balancer/BalancerTestBase.java
similarity index 82%
rename from hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/BalancerTestBase.java
rename to hbase-balancer/src/test/java/org/apache/hadoop/hbase/master/balancer/BalancerTestBase.java
index 8585b5c069a1..8288962874d5 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/BalancerTestBase.java
+++ b/hbase-balancer/src/test/java/org/apache/hadoop/hbase/master/balancer/BalancerTestBase.java
@@ -17,28 +17,24 @@
*/
package org.apache.hadoop.hbase.master.balancer;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
+import java.util.NavigableSet;
import java.util.Queue;
import java.util.Random;
import java.util.Set;
-import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.RegionInfo;
@@ -49,7 +45,6 @@
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.net.DNSToSwitchMapping;
import org.junit.Assert;
-import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -63,18 +58,6 @@ public class BalancerTestBase {
private static final Logger LOG = LoggerFactory.getLogger(BalancerTestBase.class);
static int regionId = 0;
protected static Configuration conf;
- protected static StochasticLoadBalancer loadBalancer;
-
- @BeforeClass
- public static void beforeAllTests() throws Exception {
- conf = HBaseConfiguration.create();
- conf.setClass("hbase.util.ip.to.rack.determiner", MockMapping.class, DNSToSwitchMapping.class);
- conf.setFloat("hbase.master.balancer.stochastic.maxMovePercent", 0.75f);
- conf.setFloat("hbase.regions.slop", 0.0f);
- conf.setFloat("hbase.master.balancer.stochastic.localityCost", 0);
- loadBalancer = new StochasticLoadBalancer();
- loadBalancer.setConf(conf);
- }
protected int[] largeCluster = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -165,11 +148,11 @@ public List resolve(List names) {
return Stream.generate(() -> "rack").limit(names.size()).collect(Collectors.toList());
}
- // do not add @Override annotations here. It mighty break compilation with earlier Hadoops
+ @Override
public void reloadCachedMappings() {
}
- // do not add @Override annotations here. It mighty break compilation with earlier Hadoops
+ @Override
public void reloadCachedMappings(List arg0) {
}
}
@@ -254,7 +237,7 @@ public void assertRegionReplicaPlacement(Map> serve
TreeMap> regionsPerHost = new TreeMap<>();
TreeMap> regionsPerRack = new TreeMap<>();
- for (Entry> entry : serverMap.entrySet()) {
+ for (Map.Entry> entry : serverMap.entrySet()) {
String hostname = entry.getKey().getHostname();
Set infos = regionsPerHost.get(hostname);
if (infos == null) {
@@ -274,7 +257,7 @@ public void assertRegionReplicaPlacement(Map> serve
return;
}
- for (Entry> entry : serverMap.entrySet()) {
+ for (Map.Entry> entry : serverMap.entrySet()) {
String rack = rackManager.getRack(entry.getKey());
Set infos = regionsPerRack.get(rack);
if (infos == null) {
@@ -313,7 +296,7 @@ protected List convertToList(final Map balancedCluster) {
- SortedSet sorted = new TreeSet<>(balancedCluster);
+ NavigableSet sorted = new TreeSet<>(balancedCluster);
ServerAndLoad[] arr = sorted.toArray(new ServerAndLoad[sorted.size()]);
StringBuilder sb = new StringBuilder(sorted.size() * 4 + 4);
sb.append("{ ");
@@ -332,14 +315,10 @@ protected String printMock(List balancedCluster) {
/**
* This assumes the RegionPlan HSI instances are the same ones in the map, so
* actually no need to even pass in the map, but I think it's clearer.
- *
- * @param list
- * @param plans
* @return a list of all added {@link ServerAndLoad} values.
*/
- protected List reconcile(List list,
- List plans,
- Map> servers) {
+ protected List reconcile(List list, List plans,
+ Map> servers) {
List result = new ArrayList<>(list.size());
Map map = new HashMap<>(list.size());
@@ -432,7 +411,7 @@ protected HashMap>> mockClusterS
return result;
}
- private Queue regionQueue = new LinkedList<>();
+ private Queue regionQueue = new ArrayDeque<>();
protected List randomRegions(int numRegions) {
return randomRegions(numRegions, -1);
@@ -511,7 +490,7 @@ protected void returnRegions(List regions) {
regionQueue.addAll(regions);
}
- private Queue serverQueue = new LinkedList<>();
+ private Queue serverQueue = new ArrayDeque<>();
protected ServerAndLoad randomServer(final int numRegionsPerServer) {
if (!this.serverQueue.isEmpty()) {
@@ -542,61 +521,13 @@ protected void returnServers(List servers) {
this.serverQueue.addAll(servers);
}
- protected void testWithCluster(int numNodes,
- int numRegions,
- int numRegionsPerServer,
- int replication,
- int numTables,
- boolean assertFullyBalanced, boolean assertFullyBalancedForReplicas) {
- Map> serverMap =
- createServerMap(numNodes, numRegions, numRegionsPerServer, replication, numTables);
- testWithCluster(serverMap, null, assertFullyBalanced, assertFullyBalancedForReplicas);
- }
-
- protected void testWithCluster(Map> serverMap,
- RackManager rackManager, boolean assertFullyBalanced, boolean assertFullyBalancedForReplicas) {
- List list = convertToList(serverMap);
- LOG.info("Mock Cluster : " + printMock(list) + " " + printStats(list));
-
- loadBalancer.setRackManager(rackManager);
- // Run the balancer.
- Map>> LoadOfAllTable =
- (Map) mockClusterServersWithTables(serverMap);
- List plans = loadBalancer.balanceCluster(LoadOfAllTable);
- assertNotNull("Initial cluster balance should produce plans.", plans);
-
- // Check to see that this actually got to a stable place.
- if (assertFullyBalanced || assertFullyBalancedForReplicas) {
- // Apply the plan to the mock cluster.
- List balancedCluster = reconcile(list, plans, serverMap);
-
- // Print out the cluster loads to make debugging easier.
- LOG.info("Mock Balance : " + printMock(balancedCluster));
-
- if (assertFullyBalanced) {
- assertClusterAsBalanced(balancedCluster);
- LoadOfAllTable = (Map) mockClusterServersWithTables(serverMap);
- List secondPlans = loadBalancer.balanceCluster(LoadOfAllTable);
- assertNull("Given a requirement to be fully balanced, second attempt at plans should " +
- "produce none.", secondPlans);
- }
-
- if (assertFullyBalancedForReplicas) {
- assertRegionReplicaPlacement(serverMap, rackManager);
- }
- }
- }
-
- protected Map> createServerMap(int numNodes,
- int numRegions,
- int numRegionsPerServer,
- int replication,
- int numTables) {
- //construct a cluster of numNodes, having a total of numRegions. Each RS will hold
- //numRegionsPerServer many regions except for the last one, which will host all the
- //remaining regions
+ protected Map> createServerMap(int numNodes, int numRegions,
+ int numRegionsPerServer, int replication, int numTables) {
+ // construct a cluster of numNodes, having a total of numRegions. Each RS will hold
+ // numRegionsPerServer many regions except for the last one, which will host all the
+ // remaining regions
int[] cluster = new int[numNodes];
- for (int i =0; i < numNodes; i++) {
+ for (int i = 0; i < numNodes; i++) {
cluster[i] = numRegionsPerServer;
}
cluster[cluster.length - 1] = numRegions - ((cluster.length - 1) * numRegionsPerServer);
@@ -606,7 +537,7 @@ protected Map> createServerMap(int numNodes,
for (List regions : clusterState.values()) {
int length = regions.size();
for (int i = 0; i < length; i++) {
- for (int r = 1; r < replication ; r++) {
+ for (int r = 1; r < replication; r++) {
regions.add(RegionReplicaUtil.getRegionInfoForReplica(regions.get(i), r));
}
}
@@ -615,5 +546,4 @@ protected Map> createServerMap(int numNodes,
return clusterState;
}
-
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestBaseLoadBalancer.java b/hbase-balancer/src/test/java/org/apache/hadoop/hbase/master/balancer/TestBaseLoadBalancer.java
similarity index 97%
rename from hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestBaseLoadBalancer.java
rename to hbase-balancer/src/test/java/org/apache/hadoop/hbase/master/balancer/TestBaseLoadBalancer.java
index 959300abfdae..2e33cf19a534 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestBaseLoadBalancer.java
+++ b/hbase-balancer/src/test/java/org/apache/hadoop/hbase/master/balancer/TestBaseLoadBalancer.java
@@ -45,10 +45,8 @@
import org.apache.hadoop.hbase.client.RegionInfoBuilder;
import org.apache.hadoop.hbase.client.RegionReplicaUtil;
import org.apache.hadoop.hbase.master.LoadBalancer;
-import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.RackManager;
import org.apache.hadoop.hbase.master.RegionPlan;
-import org.apache.hadoop.hbase.master.ServerManager;
import org.apache.hadoop.hbase.testclassification.MasterTests;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.util.Bytes;
@@ -94,9 +92,8 @@ public static void beforeAllTests() throws Exception {
conf.setClass("hbase.util.ip.to.rack.determiner", MockMapping.class, DNSToSwitchMapping.class);
loadBalancer = new MockBalancer();
loadBalancer.setConf(conf);
- MasterServices st = mock(MasterServices.class);
- when(st.getServerName()).thenReturn(master);
- loadBalancer.setMasterServices(st);
+ ClusterInfoProvider provider = mock(ClusterInfoProvider.class);
+ loadBalancer.setClusterInfoProvider(provider);
// Set up the rack topologies (5 machines per rack)
rackManager = mock(RackManager.class);
@@ -133,8 +130,6 @@ public List balanceTable(TableName tableName,
*
* Round-robin. Should yield a balanced cluster so same invariant as the load
* balancer holds, all servers holding either floor(avg) or ceiling(avg).
- *
- * @throws Exception
*/
@Test
public void testBulkAssignment() throws Exception {
@@ -171,7 +166,6 @@ public void testBulkAssignment() throws Exception {
/**
* Test the cluster startup bulk assignment which attempts to retain
* assignment info.
- * @throws Exception
*/
@Test
public void testRetainAssignment() throws Exception {
@@ -230,11 +224,11 @@ private void testRandomAssignment(int numberOfIdleServers) throws Exception {
Configuration conf = HBaseConfiguration.create();
conf.setClass("hbase.util.ip.to.rack.determiner", MockMapping.class, DNSToSwitchMapping.class);
balancer.setConf(conf);
- ServerManager sm = mock(ServerManager.class);
- when(sm.getOnlineServersListWithPredicator(anyList(), any())).thenReturn(idleServers);
- MasterServices services = mock(MasterServices.class);
- when(services.getServerManager()).thenReturn(sm);
- balancer.setMasterServices(services);
+ ClusterInfoProvider provider = mock(ClusterInfoProvider.class);
+ when(
+ provider.getOnlineServersListWithPredicator(anyList(), any()))
+ .thenReturn(idleServers);
+ balancer.setClusterInfoProvider(provider);
RegionInfo hri1 = RegionInfoBuilder.newBuilder(TableName.valueOf(name.getMethodName()))
.setStartKey(Bytes.toBytes("key1"))
.setEndKey(Bytes.toBytes("key2"))
@@ -406,9 +400,6 @@ private List getListOfServerNames(final List sals) {
* If a region had an existing assignment to a server with the same
* address a a currently online server, it will be assigned to it
*
- * @param existing
- * @param servers
- * @param assignment
*/
private void assertRetainedAssignment(Map existing,
List servers, Map> assignment) {
diff --git a/hbase-balancer/src/test/java/org/apache/hadoop/hbase/master/balancer/TestRegionHDFSBlockLocationFinder.java b/hbase-balancer/src/test/java/org/apache/hadoop/hbase/master/balancer/TestRegionHDFSBlockLocationFinder.java
index 41d420b5db17..f51764fd39f0 100644
--- a/hbase-balancer/src/test/java/org/apache/hadoop/hbase/master/balancer/TestRegionHDFSBlockLocationFinder.java
+++ b/hbase-balancer/src/test/java/org/apache/hadoop/hbase/master/balancer/TestRegionHDFSBlockLocationFinder.java
@@ -27,10 +27,13 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
+import java.util.function.Predicate;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.ClusterMetrics;
import org.apache.hadoop.hbase.HBaseClassTestRule;
@@ -111,6 +114,28 @@ public HDFSBlocksDistribution computeHDFSBlocksDistribution(Configuration conf,
TableDescriptor tableDescriptor, RegionInfo regionInfo) throws IOException {
return generate(regionInfo);
}
+
+ @Override
+ public boolean hasRegionReplica(Collection regions) throws IOException {
+ return false;
+ }
+
+ @Override
+ public List getOnlineServersListWithPredicator(List servers,
+ Predicate filter) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public Map>
+ getSnapShotOfAssignment(Collection regions) {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public int getNumberOfTables() {
+ return 0;
+ }
});
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestSimpleLoadBalancer.java b/hbase-balancer/src/test/java/org/apache/hadoop/hbase/master/balancer/TestSimpleLoadBalancer.java
similarity index 80%
rename from hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestSimpleLoadBalancer.java
rename to hbase-balancer/src/test/java/org/apache/hadoop/hbase/master/balancer/TestSimpleLoadBalancer.java
index 5366c64e6647..a09e53391393 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestSimpleLoadBalancer.java
+++ b/hbase-balancer/src/test/java/org/apache/hadoop/hbase/master/balancer/TestSimpleLoadBalancer.java
@@ -34,7 +34,6 @@
import org.apache.hadoop.hbase.master.RegionPlan;
import org.apache.hadoop.hbase.testclassification.MasterTests;
import org.apache.hadoop.hbase.testclassification.SmallTests;
-import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.net.DNSToSwitchMapping;
import org.junit.BeforeClass;
import org.junit.ClassRule;
@@ -68,57 +67,7 @@ public static void beforeAllTests() throws Exception {
loadBalancer.setConf(conf);
}
- // int[testnum][servernumber] -> numregions
- int[][] clusterStateMocks = new int[][] {
- // 1 node
- new int[] { 0 },
- new int[] { 1 },
- new int[] { 10 },
- // 2 node
- new int[] { 0, 0 },
- new int[] { 2, 0 },
- new int[] { 2, 1 },
- new int[] { 2, 2 },
- new int[] { 2, 3 },
- new int[] { 2, 4 },
- new int[] { 1, 1 },
- new int[] { 0, 1 },
- new int[] { 10, 1 },
- new int[] { 14, 1432 },
- new int[] { 47, 53 },
- // 3 node
- new int[] { 0, 1, 2 },
- new int[] { 1, 2, 3 },
- new int[] { 0, 2, 2 },
- new int[] { 0, 3, 0 },
- new int[] { 0, 4, 0 },
- new int[] { 20, 20, 0 },
- // 4 node
- new int[] { 0, 1, 2, 3 },
- new int[] { 4, 0, 0, 0 },
- new int[] { 5, 0, 0, 0 },
- new int[] { 6, 6, 0, 0 },
- new int[] { 6, 2, 0, 0 },
- new int[] { 6, 1, 0, 0 },
- new int[] { 6, 0, 0, 0 },
- new int[] { 4, 4, 4, 7 },
- new int[] { 4, 4, 4, 8 },
- new int[] { 0, 0, 0, 7 },
- // 5 node
- new int[] { 1, 1, 1, 1, 4 },
- // more nodes
- new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
- new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 10 }, new int[] { 6, 6, 5, 6, 6, 6, 6, 6, 6, 1 },
- new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 54 }, new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 55 },
- new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 56 }, new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 },
- new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 8 }, new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 9 },
- new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 10 }, new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 123 },
- new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 155 },
- new int[] { 0, 0, 144, 1, 1, 1, 1, 1123, 133, 138, 12, 1444 },
- new int[] { 0, 0, 144, 1, 0, 4, 1, 1123, 133, 138, 12, 1444 },
- new int[] { 1538, 1392, 1561, 1557, 1535, 1553, 1385, 1542, 1619 } };
-
- int [] mockUniformCluster = new int[] { 5, 5, 5, 5, 5 ,0};
+ int[] mockUniformCluster = new int[] { 5, 5, 5, 5, 5, 0 };
@Rule
public TestName name = new TestName();
@@ -140,7 +89,6 @@ public void testBalanceClusterOverall() throws Exception {
mockClusterServersWithTables(clusterServers);
loadBalancer.setClusterLoad(clusterLoad);
List clusterplans = new ArrayList<>();
- List> regionAmountList = new ArrayList<>();
for (Map.Entry>> mapEntry : result
.entrySet()) {
TableName tableName = mapEntry.getKey();
@@ -169,7 +117,6 @@ public void testBalanceClusterOverall() throws Exception {
* ceiling(average) at both table level and cluster level
* Deliberately generate a special case to show the overall strategy can achieve cluster
* level balance while the bytable strategy cannot
- * @throws Exception
*/
@Test
public void testImpactOfBalanceClusterOverall() throws Exception {
@@ -196,7 +143,6 @@ private void testImpactOfBalanceClusterOverall(boolean useLoadOfAllTable) throws
loadBalancer.setClusterLoad(clusterLoad);
}
List clusterplans1 = new ArrayList();
- List> regionAmountList = new ArrayList>();
for (Map.Entry>> mapEntry : LoadOfAllTable
.entrySet()) {
TableName tableName = mapEntry.getKey();
diff --git a/hbase-server/pom.xml b/hbase-server/pom.xml
index 858835749b9a..3678dbd9157a 100644
--- a/hbase-server/pom.xml
+++ b/hbase-server/pom.xml
@@ -296,6 +296,12 @@
org.apache.hbase
hbase-balancer
+
+ hbase-balancer
+ org.apache.hbase
+ test-jar
+ test
+
org.apache.hbase
hbase-common
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/favored/FavoredNodeLoadBalancer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/favored/FavoredNodeLoadBalancer.java
index 60a2c6cae13f..aa3642affe60 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/favored/FavoredNodeLoadBalancer.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/favored/FavoredNodeLoadBalancer.java
@@ -29,7 +29,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseIOException;
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
@@ -38,6 +37,7 @@
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.favored.FavoredNodesPlan.Position;
+import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.RackManager;
import org.apache.hadoop.hbase.master.RegionPlan;
import org.apache.hadoop.hbase.master.ServerManager;
@@ -70,6 +70,7 @@
public class FavoredNodeLoadBalancer extends BaseLoadBalancer implements FavoredNodesPromoter {
private static final Logger LOG = LoggerFactory.getLogger(FavoredNodeLoadBalancer.class);
+ private MasterServices services;
private RackManager rackManager;
private Configuration conf;
private FavoredNodesManager fnm;
@@ -79,6 +80,10 @@ public void setConf(Configuration conf) {
this.conf = conf;
}
+ public void setMasterServices(MasterServices services) {
+ this.services = services;
+ }
+
@Override
public synchronized void initialize() throws HBaseIOException {
super.initialize();
@@ -95,7 +100,7 @@ public List balanceTable(TableName tableName,
List plans = new ArrayList<>();
// perform a scan of the meta to get the latest updates (if any)
SnapshotOfRegionAssignmentFromMeta snaphotOfRegionAssignment =
- new SnapshotOfRegionAssignmentFromMeta(super.services.getConnection());
+ new SnapshotOfRegionAssignmentFromMeta(services.getConnection());
try {
snaphotOfRegionAssignment.initialize();
} catch (IOException ie) {
@@ -105,7 +110,7 @@ public List balanceTable(TableName tableName,
// This is not used? Findbugs says so: Map
// serverNameToServerNameWithoutCode = new HashMap<>();
Map serverNameWithoutCodeToServerName = new HashMap<>();
- ServerManager serverMgr = super.services.getServerManager();
+ ServerManager serverMgr = services.getServerManager();
for (ServerName sn : serverMgr.getOnlineServersList()) {
ServerName s = ServerName.valueOf(sn.getHostname(), sn.getPort(), ServerName.NON_STARTCODE);
// FindBugs complains about useless store! serverNameToServerNameWithoutCode.put(sn, s);
@@ -136,9 +141,9 @@ public List balanceTable(TableName tableName,
}
// the region is currently on none of the favored nodes
// get it on one of them if possible
- ServerMetrics l1 = super.services.getServerManager()
+ ServerMetrics l1 = services.getServerManager()
.getLoad(serverNameWithoutCodeToServerName.get(favoredNodes.get(1)));
- ServerMetrics l2 = super.services.getServerManager()
+ ServerMetrics l2 = services.getServerManager()
.getLoad(serverNameWithoutCodeToServerName.get(favoredNodes.get(2)));
if (l1 != null && l2 != null) {
if (l1.getRegionMetrics().size() > l2.getRegionMetrics().size()) {
@@ -245,10 +250,11 @@ public ServerName randomAssignment(RegionInfo regionInfo, List serve
}
private Pair
+
+ hbase-balancer
+ org.apache.hbase
+ ${project.version}
+ test-jar
+ test
+
hbase-http
org.apache.hbase