From ae6e6d602af9ca08793ad03ef211b2cf329429ef Mon Sep 17 00:00:00 2001 From: Umesh Agashe Date: Sat, 15 Jul 2017 22:51:05 -0700 Subject: [PATCH] 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 --- .../protobuf/generated/MasterProcedureProtos.java | 113 ++++++++++++++++----- .../src/main/protobuf/MasterProcedure.proto | 3 +- .../hbase/master/assignment/AssignmentManager.java | 42 ++++++-- .../master/assignment/MoveRegionProcedure.java | 15 ++- 4 files changed, 131 insertions(+), 42 deletions(-) diff --git a/hbase-protocol-shaded/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/generated/MasterProcedureProtos.java b/hbase-protocol-shaded/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/generated/MasterProcedureProtos.java index 853c177539ad0092d3840ad71e79f55ccb05aee4..14afba2b5cc55bfa9f9f1fdab99911d930ed71b9 100644 --- a/hbase-protocol-shaded/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/generated/MasterProcedureProtos.java +++ b/hbase-protocol-shaded/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/generated/MasterProcedureProtos.java @@ -28981,15 +28981,27 @@ public final class MasterProcedureProtos { org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerNameOrBuilder getSourceServerOrBuilder(); /** - * required .hbase.pb.ServerName destination_server = 3; + *
+     * if destination server not specified, its selected with load balancer
+     * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ boolean hasDestinationServer(); /** - * required .hbase.pb.ServerName destination_server = 3; + *
+     * if destination server not specified, its selected with load balancer
+     * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName getDestinationServer(); /** - * required .hbase.pb.ServerName destination_server = 3; + *
+     * if destination server not specified, its selected with load balancer
+     * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerNameOrBuilder getDestinationServerOrBuilder(); } @@ -29144,19 +29156,31 @@ public final class MasterProcedureProtos { public static final int DESTINATION_SERVER_FIELD_NUMBER = 3; private org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName destinationServer_; /** - * required .hbase.pb.ServerName destination_server = 3; + *
+     * if destination server not specified, its selected with load balancer
+     * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ public boolean hasDestinationServer() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** - * required .hbase.pb.ServerName destination_server = 3; + *
+     * if destination server not specified, its selected with load balancer
+     * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ public org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName getDestinationServer() { return destinationServer_ == null ? org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName.getDefaultInstance() : destinationServer_; } /** - * required .hbase.pb.ServerName destination_server = 3; + *
+     * if destination server not specified, its selected with load balancer
+     * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ public org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerNameOrBuilder getDestinationServerOrBuilder() { return destinationServer_ == null ? org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName.getDefaultInstance() : destinationServer_; @@ -29172,10 +29196,6 @@ public final class MasterProcedureProtos { memoizedIsInitialized = 0; return false; } - if (!hasDestinationServer()) { - memoizedIsInitialized = 0; - return false; - } if (hasRegionInfo()) { if (!getRegionInfo().isInitialized()) { memoizedIsInitialized = 0; @@ -29186,9 +29206,11 @@ public final class MasterProcedureProtos { memoizedIsInitialized = 0; return false; } - if (!getDestinationServer().isInitialized()) { - memoizedIsInitialized = 0; - return false; + if (hasDestinationServer()) { + if (!getDestinationServer().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } } memoizedIsInitialized = 1; return true; @@ -29527,9 +29549,6 @@ public final class MasterProcedureProtos { if (!hasSourceServer()) { return false; } - if (!hasDestinationServer()) { - return false; - } if (hasRegionInfo()) { if (!getRegionInfo().isInitialized()) { return false; @@ -29538,8 +29557,10 @@ public final class MasterProcedureProtos { if (!getSourceServer().isInitialized()) { return false; } - if (!getDestinationServer().isInitialized()) { - return false; + if (hasDestinationServer()) { + if (!getDestinationServer().isInitialized()) { + return false; + } } return true; } @@ -29803,13 +29824,21 @@ public final class MasterProcedureProtos { private org.apache.hadoop.hbase.shaded.com.google.protobuf.SingleFieldBuilderV3< org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName, org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName.Builder, org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerNameOrBuilder> destinationServerBuilder_; /** - * required .hbase.pb.ServerName destination_server = 3; + *
+       * if destination server not specified, its selected with load balancer
+       * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ public boolean hasDestinationServer() { return ((bitField0_ & 0x00000004) == 0x00000004); } /** - * required .hbase.pb.ServerName destination_server = 3; + *
+       * if destination server not specified, its selected with load balancer
+       * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ public org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName getDestinationServer() { if (destinationServerBuilder_ == null) { @@ -29819,7 +29848,11 @@ public final class MasterProcedureProtos { } } /** - * required .hbase.pb.ServerName destination_server = 3; + *
+       * if destination server not specified, its selected with load balancer
+       * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ public Builder setDestinationServer(org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName value) { if (destinationServerBuilder_ == null) { @@ -29835,7 +29868,11 @@ public final class MasterProcedureProtos { return this; } /** - * required .hbase.pb.ServerName destination_server = 3; + *
+       * if destination server not specified, its selected with load balancer
+       * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ public Builder setDestinationServer( org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName.Builder builderForValue) { @@ -29849,7 +29886,11 @@ public final class MasterProcedureProtos { return this; } /** - * required .hbase.pb.ServerName destination_server = 3; + *
+       * if destination server not specified, its selected with load balancer
+       * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ public Builder mergeDestinationServer(org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName value) { if (destinationServerBuilder_ == null) { @@ -29869,7 +29910,11 @@ public final class MasterProcedureProtos { return this; } /** - * required .hbase.pb.ServerName destination_server = 3; + *
+       * if destination server not specified, its selected with load balancer
+       * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ public Builder clearDestinationServer() { if (destinationServerBuilder_ == null) { @@ -29882,7 +29927,11 @@ public final class MasterProcedureProtos { return this; } /** - * required .hbase.pb.ServerName destination_server = 3; + *
+       * if destination server not specified, its selected with load balancer
+       * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ public org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName.Builder getDestinationServerBuilder() { bitField0_ |= 0x00000004; @@ -29890,7 +29939,11 @@ public final class MasterProcedureProtos { return getDestinationServerFieldBuilder().getBuilder(); } /** - * required .hbase.pb.ServerName destination_server = 3; + *
+       * if destination server not specified, its selected with load balancer
+       * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ public org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerNameOrBuilder getDestinationServerOrBuilder() { if (destinationServerBuilder_ != null) { @@ -29901,7 +29954,11 @@ public final class MasterProcedureProtos { } } /** - * required .hbase.pb.ServerName destination_server = 3; + *
+       * if destination server not specified, its selected with load balancer
+       * 
+ * + * optional .hbase.pb.ServerName destination_server = 3; */ private org.apache.hadoop.hbase.shaded.com.google.protobuf.SingleFieldBuilderV3< org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName, org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName.Builder, org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerNameOrBuilder> @@ -31822,7 +31879,7 @@ public final class MasterProcedureProtos { "gionStateData\022)\n\013region_info\030\001 \001(\0132\024.hba" + "se.pb.RegionInfo\022+\n\rsource_server\030\002 \002(\0132" + "\024.hbase.pb.ServerName\0220\n\022destination_ser" + - "ver\030\003 \002(\0132\024.hbase.pb.ServerName\">\n\021GCReg" + + "ver\030\003 \001(\0132\024.hbase.pb.ServerName\">\n\021GCReg" + "ionStateData\022)\n\013region_info\030\001 \002(\0132\024.hbas" + "e.pb.RegionInfo\"\226\001\n\030GCMergedRegionsState" + "Data\022&\n\010parent_a\030\001 \002(\0132\024.hbase.pb.Region" + diff --git a/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto b/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto index 74ae16d2cb4a0490054b98f8928af3b3c3ba23e8..70753c689c668707f48a365bb462ef4d79232068 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 255ea5ea38fa0b944fa5d53aa429b3f99ec8d846..543a826026e8332357749fcee380b431b41425ce 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 @@ -485,8 +485,8 @@ public class AssignmentManager implements ServerListener { 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 +1648,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 +1664,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 +1683,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.info("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 d8c1b7de3b55aedbffe99b821de99b2870fb2d34..2f6081978810ead825395a6034897802e351a190 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