HBASE-24139 : Balancer should avoid leaving idle region servers (#1511)
Co-authored-by: Viraj Jasani <vjasani@apache.org> Signed-off-by: Viraj Jasani <vjasani@apache.org> Signed-off-by: Sean Busbey <busbey@apache.org> Signed-off-by: Anoop Sam John <anoopsamjohn@apache.org>
This commit is contained in:
parent
7cf97016b9
commit
aaa6450d40
@ -1297,6 +1297,10 @@ public abstract class BaseLoadBalancer implements LoadBalancer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(areSomeRegionReplicasColocated(c)) return true;
|
if(areSomeRegionReplicasColocated(c)) return true;
|
||||||
|
if(idleRegionServerExist(c)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if we even need to do any load balancing
|
// Check if we even need to do any load balancing
|
||||||
// HBASE-3681 check sloppiness first
|
// HBASE-3681 check sloppiness first
|
||||||
float average = cs.getLoadAverage(); // for logging
|
float average = cs.getLoadAverage(); // for logging
|
||||||
@ -1328,6 +1332,20 @@ public abstract class BaseLoadBalancer implements LoadBalancer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final boolean idleRegionServerExist(Cluster c){
|
||||||
|
boolean isServerExistsWithMoreRegions = false;
|
||||||
|
boolean isServerExistsWithZeroRegions = false;
|
||||||
|
for (int[] serverList: c.regionsPerServer){
|
||||||
|
if (serverList.length > 1) {
|
||||||
|
isServerExistsWithMoreRegions = true;
|
||||||
|
}
|
||||||
|
if (serverList.length == 0) {
|
||||||
|
isServerExistsWithZeroRegions = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isServerExistsWithMoreRegions && isServerExistsWithZeroRegions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a bulk assignment plan to be used on cluster startup using a
|
* Generates a bulk assignment plan to be used on cluster startup using a
|
||||||
* simple round-robin assignment.
|
* simple round-robin assignment.
|
||||||
|
@ -329,6 +329,10 @@ public class StochasticLoadBalancer extends BaseLoadBalancer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (idleRegionServerExist(cluster)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
double total = 0.0;
|
double total = 0.0;
|
||||||
float sumMultiplier = 0.0f;
|
float sumMultiplier = 0.0f;
|
||||||
for (CostFunction c : costFunctions) {
|
for (CostFunction c : costFunctions) {
|
||||||
|
@ -39,6 +39,7 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.hbase.ClusterStatus;
|
import org.apache.hadoop.hbase.ClusterStatus;
|
||||||
import org.apache.hadoop.hbase.HBaseConfiguration;
|
import org.apache.hadoop.hbase.HBaseConfiguration;
|
||||||
|
import org.apache.hadoop.hbase.HConstants;
|
||||||
import org.apache.hadoop.hbase.HRegionInfo;
|
import org.apache.hadoop.hbase.HRegionInfo;
|
||||||
import org.apache.hadoop.hbase.RegionLoad;
|
import org.apache.hadoop.hbase.RegionLoad;
|
||||||
import org.apache.hadoop.hbase.ServerLoad;
|
import org.apache.hadoop.hbase.ServerLoad;
|
||||||
@ -161,11 +162,17 @@ public class TestStochasticLoadBalancer extends BalancerTestBase {
|
|||||||
float minCost = conf.getFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 0.05f);
|
float minCost = conf.getFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 0.05f);
|
||||||
conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 1.0f);
|
conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 1.0f);
|
||||||
try {
|
try {
|
||||||
|
// Test with/without per table balancer.
|
||||||
|
boolean[] perTableBalancerConfigs = {true, false};
|
||||||
|
for (boolean isByTable : perTableBalancerConfigs) {
|
||||||
|
conf.setBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);
|
||||||
loadBalancer.setConf(conf);
|
loadBalancer.setConf(conf);
|
||||||
for (int[] mockCluster : clusterStateMocks) {
|
for (int[] mockCluster : clusterStateMocks) {
|
||||||
Map<ServerName, List<HRegionInfo>> servers = mockClusterServers(mockCluster);
|
Map<ServerName, List<HRegionInfo>> servers = mockClusterServers(mockCluster);
|
||||||
List<RegionPlan> plans = loadBalancer.balanceCluster(servers);
|
List<RegionPlan> plans = loadBalancer.balanceCluster(servers);
|
||||||
assertNull(plans);
|
boolean emptyPlans = plans == null || plans.isEmpty();
|
||||||
|
assertTrue(emptyPlans || needsBalanceIdleRegion(mockCluster));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
// reset config
|
// reset config
|
||||||
@ -684,6 +691,19 @@ public class TestStochasticLoadBalancer extends BalancerTestBase {
|
|||||||
contains(DummyCostFunction.class.getSimpleName()));
|
contains(DummyCostFunction.class.getSimpleName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean needsBalanceIdleRegion(int[] clusters) {
|
||||||
|
boolean b1 = false;
|
||||||
|
boolean b2 = false;
|
||||||
|
for (int cluster : clusters) {
|
||||||
|
if (cluster > 1) {
|
||||||
|
b1 = true;
|
||||||
|
} else {
|
||||||
|
b2 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b1 && b2;
|
||||||
|
}
|
||||||
|
|
||||||
// This mock allows us to test the LocalityCostFunction
|
// This mock allows us to test the LocalityCostFunction
|
||||||
private class MockCluster extends BaseLoadBalancer.Cluster {
|
private class MockCluster extends BaseLoadBalancer.Cluster {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user