HBASE-18492 [AMv2] Embed code for selecting highest versioned region server for system table regions in AssignmentManager.processAssignQueue()

* Modified AssignmentManager.processAssignQueue() method to consider only highest versioned region servers for system table regions when
  destination server is not specified for them. Destination server is retained, if specified.
* Modified MoveRegionProcedure to allow null value for destination server i.e. moving a region from specific source server to non-specific/ unknown
  destination server (picked by load-balancer) is supported now.
* Removed destination server selection from HMaster.checkIfShouldMoveSystemRegionAsync(), as destination server will be picked by load balancer

Signed-off-by: Michael Stack <stack@apache.org>
This commit is contained in:
Umesh Agashe 2017-07-15 22:51:05 -07:00 committed by Michael Stack
parent 03390684cc
commit f314b5911b
3 changed files with 46 additions and 16 deletions

View File

@ -387,7 +387,8 @@ enum MoveRegionState {
message MoveRegionStateData {
optional RegionInfo region_info = 1;
required ServerName source_server = 2;
required ServerName destination_server = 3;
// if destination server not specified, its selected with load balancer
optional ServerName destination_server = 3;
}
enum GCRegionState {

View File

@ -478,15 +478,13 @@ public class AssignmentManager implements ServerListener {
new Thread(() -> {
try {
synchronized (checkIfShouldMoveSystemRegionLock) {
List<ServerName> serverList = master.getServerManager()
.createDestinationServersList(getExcludedServersForSystemTable());
List<RegionPlan> plans = new ArrayList<>();
for (ServerName server : getExcludedServersForSystemTable()) {
List<HRegionInfo> regionsShouldMove = getCarryingSystemTables(server);
if (!regionsShouldMove.isEmpty()) {
for (HRegionInfo regionInfo : regionsShouldMove) {
RegionPlan plan = new RegionPlan(regionInfo, server,
getBalancer().randomAssignment(regionInfo, serverList));
// null value for dest forces destination server to be selected by balancer
RegionPlan plan = new RegionPlan(regionInfo, server, null);
if (regionInfo.isMetaRegion()) {
// Must move meta region first.
moveAsync(plan);
@ -1648,9 +1646,14 @@ public class AssignmentManager implements ServerListener {
}
// TODO: Optimize balancer. pass a RegionPlan?
final HashMap<HRegionInfo, ServerName> retainMap = new HashMap<HRegionInfo, ServerName>();
final List<HRegionInfo> rrList = new ArrayList<HRegionInfo>();
for (RegionStateNode regionNode: regions.values()) {
final HashMap<HRegionInfo, ServerName> retainMap = new HashMap<>();
final List<HRegionInfo> userRRList = new ArrayList<>();
// regions for system tables requiring reassignment
final List<HRegionInfo> sysRRList = new ArrayList<>();
for (RegionStateNode regionNode : regions.values()) {
boolean sysTable = regionNode.isSystemTable();
final List<HRegionInfo> rrList = sysTable ? sysRRList : userRRList;
if (regionNode.getRegionLocation() != null) {
retainMap.put(regionNode.getRegionInfo(), regionNode.getRegionLocation());
} else {
@ -1659,7 +1662,6 @@ public class AssignmentManager implements ServerListener {
}
// TODO: connect with the listener to invalidate the cache
final LoadBalancer balancer = getBalancer();
// TODO use events
List<ServerName> servers = master.getServerManager().createDestinationServersList();
@ -1679,13 +1681,35 @@ public class AssignmentManager implements ServerListener {
servers = master.getServerManager().createDestinationServersList();
}
final boolean isTraceEnabled = LOG.isTraceEnabled();
if (!sysRRList.isEmpty()) {
// system table regions requiring reassignment are present, get region servers
// not available for system table regions
final List<ServerName> excludeServers = getExcludedServersForSystemTable();
List<ServerName> serversForSysTables = servers.stream()
.filter(s -> !excludeServers.contains(s)).collect(Collectors.toList());
if (serversForSysTables.isEmpty()) {
LOG.warn("No servers available for system table regions, considering all servers!");
}
LOG.debug("Processing assignment plans for System tables sysServersCount=" +
serversForSysTables.size() + ", allServersCount=" + servers.size());
processAssignmentPlans(regions, null, sysRRList,
serversForSysTables.isEmpty() ? servers : serversForSysTables);
}
processAssignmentPlans(regions, retainMap, userRRList, servers);
}
private void processAssignmentPlans(final HashMap<HRegionInfo, RegionStateNode> regions,
final HashMap<HRegionInfo, ServerName> retainMap, final List<HRegionInfo> rrList,
final List<ServerName> servers) {
boolean isTraceEnabled = LOG.isTraceEnabled();
if (isTraceEnabled) {
LOG.trace("available servers count=" + servers.size() + ": " + servers);
}
final LoadBalancer balancer = getBalancer();
// ask the balancer where to place regions
if (!retainMap.isEmpty()) {
if (retainMap != null && !retainMap.isEmpty()) {
if (isTraceEnabled) {
LOG.trace("retain assign regions=" + retainMap);
}

View File

@ -54,7 +54,6 @@ public class MoveRegionProcedure extends AbstractStateMachineRegionProcedure<Mov
public MoveRegionProcedure(final MasterProcedureEnv env, final RegionPlan plan) {
super(env, plan.getRegionInfo());
assert plan.getDestination() != null: plan.toString();
this.plan = plan;
}
@ -70,7 +69,10 @@ public class MoveRegionProcedure extends AbstractStateMachineRegionProcedure<Mov
setNextState(MoveRegionState.MOVE_REGION_ASSIGN);
break;
case MOVE_REGION_ASSIGN:
addChildProcedure(new AssignProcedure(plan.getRegionInfo(), plan.getDestination()));
AssignProcedure assignProcedure = plan.getDestination() == null ?
new AssignProcedure(plan.getRegionInfo(), true) :
new AssignProcedure(plan.getRegionInfo(), plan.getDestination());
addChildProcedure(assignProcedure);
return Flow.NO_MORE_STATE;
default:
throw new UnsupportedOperationException("unhandled state=" + state);
@ -127,8 +129,10 @@ public class MoveRegionProcedure extends AbstractStateMachineRegionProcedure<Mov
final MoveRegionStateData.Builder state = MoveRegionStateData.newBuilder()
// No need to serialize the HRegionInfo. The super class has the region.
.setSourceServer(ProtobufUtil.toServerName(plan.getSource()))
.setDestinationServer(ProtobufUtil.toServerName(plan.getDestination()));
.setSourceServer(ProtobufUtil.toServerName(plan.getSource()));
if (plan.getDestination() != null) {
state.setDestinationServer(ProtobufUtil.toServerName(plan.getDestination()));
}
state.build().writeDelimitedTo(stream);
}
@ -139,7 +143,8 @@ public class MoveRegionProcedure extends AbstractStateMachineRegionProcedure<Mov
final MoveRegionStateData state = MoveRegionStateData.parseDelimitedFrom(stream);
final HRegionInfo regionInfo = getRegion(); // Get it from super class deserialization.
final ServerName sourceServer = ProtobufUtil.toServerName(state.getSourceServer());
final ServerName destinationServer = ProtobufUtil.toServerName(state.getDestinationServer());
final ServerName destinationServer = state.hasDestinationServer() ?
ProtobufUtil.toServerName(state.getDestinationServer()) : null;
this.plan = new RegionPlan(regionInfo, sourceServer, destinationServer);
}
}