use of org.apache.hadoop.hbase.ServerName in project hbase by apache.
the class MergeTableRegionsProcedure method isRegionsOnTheSameServer.
/**
* The procedure could be restarted from a different machine. If the variable is null, we need to
* retrieve it.
* @param env MasterProcedureEnv
* @return whether target regions hosted by the same RS
*/
private boolean isRegionsOnTheSameServer(final MasterProcedureEnv env) throws IOException {
Boolean onSameRS = true;
int i = 0;
RegionStates regionStates = getAssignmentManager(env).getRegionStates();
regionLocation = regionStates.getRegionServerOfRegion(regionsToMerge[i]);
if (regionLocation != null) {
for (i = 1; i < regionsToMerge.length; i++) {
ServerName regionLocation2 = regionStates.getRegionServerOfRegion(regionsToMerge[i]);
if (regionLocation2 != null) {
if (onSameRS) {
onSameRS = regionLocation.equals(regionLocation2);
}
} else {
// At least one region is not online, merge will fail, no need to continue.
break;
}
}
if (i == regionsToMerge.length) {
// Finish checking all regions, return the result;
return onSameRS;
}
}
// If reaching here, at least one region is not online.
String msg = "Skip merging regions " + getRegionsToMergeListFullNameString() + ", because region " + regionsToMerge[i].getEncodedName() + " is not online now.";
LOG.warn(msg);
throw new IOException(msg);
}
use of org.apache.hadoop.hbase.ServerName in project hbase by apache.
the class MergeTableRegionsProcedure method MoveRegionsToSameRS.
/**
* Move all regions to the same region server
* @param env MasterProcedureEnv
* @return whether target regions hosted by the same RS
* @throws IOException
*/
private boolean MoveRegionsToSameRS(final MasterProcedureEnv env) throws IOException {
// Make sure regions are on the same regionserver before send merge
// regions request to region server.
//
boolean onSameRS = isRegionsOnTheSameServer(env);
if (!onSameRS) {
// Note: the following logic assumes that we only have 2 regions to merge. In the future,
// if we want to extend to more than 2 regions, the code needs to modify a little bit.
//
RegionStates regionStates = getAssignmentManager(env).getRegionStates();
ServerName regionLocation2 = regionStates.getRegionServerOfRegion(regionsToMerge[1]);
RegionLoad loadOfRegionA = getRegionLoad(env, regionLocation, regionsToMerge[0]);
RegionLoad loadOfRegionB = getRegionLoad(env, regionLocation2, regionsToMerge[1]);
if (loadOfRegionA != null && loadOfRegionB != null && loadOfRegionA.getRequestsCount() < loadOfRegionB.getRequestsCount()) {
// switch regionsToMerge[0] and regionsToMerge[1]
HRegionInfo tmpRegion = this.regionsToMerge[0];
this.regionsToMerge[0] = this.regionsToMerge[1];
this.regionsToMerge[1] = tmpRegion;
ServerName tmpLocation = regionLocation;
regionLocation = regionLocation2;
regionLocation2 = tmpLocation;
}
long startTime = EnvironmentEdgeManager.currentTime();
RegionPlan regionPlan = new RegionPlan(regionsToMerge[1], regionLocation2, regionLocation);
LOG.info("Moving regions to same server for merge: " + regionPlan.toString());
getAssignmentManager(env).balance(regionPlan);
do {
try {
Thread.sleep(20);
// Make sure check RIT first, then get region location, otherwise
// we would make a wrong result if region is online between getting
// region location and checking RIT
boolean isRIT = regionStates.isRegionInTransition(regionsToMerge[1]);
regionLocation2 = regionStates.getRegionServerOfRegion(regionsToMerge[1]);
onSameRS = regionLocation.equals(regionLocation2);
if (onSameRS || !isRIT) {
// RegionInTransition any more
break;
}
} catch (InterruptedException e) {
InterruptedIOException iioe = new InterruptedIOException();
iioe.initCause(e);
throw iioe;
}
} while ((EnvironmentEdgeManager.currentTime() - startTime) <= getTimeout(env));
}
return onSameRS;
}
use of org.apache.hadoop.hbase.ServerName in project hbase by apache.
the class StochasticLoadBalancer method updateRegionLoad.
/**
* Store the current region loads.
*/
private synchronized void updateRegionLoad() {
// We create a new hashmap so that regions that are no longer there are removed.
// However we temporarily need the old loads so we can use them to keep the rolling average.
Map<String, Deque<BalancerRegionLoad>> oldLoads = loads;
loads = new HashMap<>();
for (ServerName sn : clusterStatus.getServers()) {
ServerLoad sl = clusterStatus.getLoad(sn);
if (sl == null) {
continue;
}
for (Entry<byte[], RegionLoad> entry : sl.getRegionsLoad().entrySet()) {
Deque<BalancerRegionLoad> rLoads = oldLoads.get(Bytes.toString(entry.getKey()));
if (rLoads == null) {
// There was nothing there
rLoads = new ArrayDeque<>();
} else if (rLoads.size() >= numRegionLoadsToRemember) {
rLoads.remove();
}
rLoads.add(new BalancerRegionLoad(entry.getValue()));
loads.put(Bytes.toString(entry.getKey()), rLoads);
}
}
for (CostFromRegionLoadFunction cost : regionLoadFunctions) {
cost.setLoads(loads);
}
}
use of org.apache.hadoop.hbase.ServerName in project hbase by apache.
the class BaseLoadBalancer method balanceMasterRegions.
/**
* Balance the regions that should be on master regionserver.
*/
protected List<RegionPlan> balanceMasterRegions(Map<ServerName, List<HRegionInfo>> clusterMap) {
if (masterServerName == null || clusterMap == null || clusterMap.size() <= 1)
return null;
List<RegionPlan> plans = null;
List<HRegionInfo> regions = clusterMap.get(masterServerName);
if (regions != null) {
Iterator<ServerName> keyIt = null;
for (HRegionInfo region : regions) {
if (shouldBeOnMaster(region))
continue;
// Find a non-master regionserver to host the region
if (keyIt == null || !keyIt.hasNext()) {
keyIt = clusterMap.keySet().iterator();
}
ServerName dest = keyIt.next();
if (masterServerName.equals(dest)) {
if (!keyIt.hasNext()) {
keyIt = clusterMap.keySet().iterator();
}
dest = keyIt.next();
}
// Move this region away from the master regionserver
RegionPlan plan = new RegionPlan(region, masterServerName, dest);
if (plans == null) {
plans = new ArrayList<>();
}
plans.add(plan);
}
}
for (Map.Entry<ServerName, List<HRegionInfo>> server : clusterMap.entrySet()) {
if (masterServerName.equals(server.getKey()))
continue;
for (HRegionInfo region : server.getValue()) {
if (!shouldBeOnMaster(region))
continue;
// Move this region to the master regionserver
RegionPlan plan = new RegionPlan(region, server.getKey(), masterServerName);
if (plans == null) {
plans = new ArrayList<>();
}
plans.add(plan);
}
}
return plans;
}
use of org.apache.hadoop.hbase.ServerName in project hbase by apache.
the class BaseLoadBalancer method randomAssignment.
/**
* Used to assign a single region to a random server.
*/
private ServerName randomAssignment(Cluster cluster, HRegionInfo regionInfo, List<ServerName> servers) {
// servers is not null, numServers > 1
int numServers = servers.size();
ServerName sn = null;
final int maxIterations = numServers * 4;
int iterations = 0;
do {
int i = RANDOM.nextInt(numServers);
sn = servers.get(i);
} while (cluster.wouldLowerAvailability(regionInfo, sn) && iterations++ < maxIterations);
cluster.doAssignRegion(regionInfo, sn);
return sn;
}
Aggregations