diff --git a/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto b/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto index 74ae16d2cb4..70753c689c6 100644 --- a/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto +++ b/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto @@ -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 { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java index 255ea5ea38f..54cb1cadc0e 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java @@ -478,15 +478,13 @@ public class AssignmentManager implements ServerListener { new Thread(() -> { try { synchronized (checkIfShouldMoveSystemRegionLock) { - List serverList = master.getServerManager() - .createDestinationServersList(getExcludedServersForSystemTable()); List plans = new ArrayList<>(); for (ServerName server : getExcludedServersForSystemTable()) { List 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 retainMap = new HashMap(); - final List rrList = new ArrayList(); - for (RegionStateNode regionNode: regions.values()) { + final HashMap retainMap = new HashMap<>(); + final List userRRList = new ArrayList<>(); + // regions for system tables requiring reassignment + final List sysRRList = new ArrayList<>(); + for (RegionStateNode regionNode : regions.values()) { + boolean sysTable = regionNode.isSystemTable(); + final List 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 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 excludeServers = getExcludedServersForSystemTable(); + List 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 regions, + final HashMap retainMap, final List rrList, + final List 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); } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/MoveRegionProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/MoveRegionProcedure.java index d8c1b7de3b5..1907e9838d8 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/MoveRegionProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/MoveRegionProcedure.java @@ -54,7 +54,6 @@ public class MoveRegionProcedure extends AbstractStateMachineRegionProcedure