diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/favored/FavoredNodeLoadBalancer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/favored/FavoredNodeLoadBalancer.java index b8d4b09c0f53..52a37a2c5d08 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/favored/FavoredNodeLoadBalancer.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/favored/FavoredNodeLoadBalancer.java @@ -321,6 +321,7 @@ private void addRegionToMap(Map> assignmentMapForFa regionsOnServer.add(region); } + @Override public synchronized List getFavoredNodes(RegionInfo regionInfo) { return this.fnm.getFavoredNodes(regionInfo); } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/favored/FavoredNodesPromoter.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/favored/FavoredNodesPromoter.java index 322eb1df0d25..a24fce0af491 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/favored/FavoredNodesPromoter.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/favored/FavoredNodesPromoter.java @@ -35,4 +35,6 @@ void generateFavoredNodesForDaughter(List servers, void generateFavoredNodesForMergedRegion(RegionInfo merged, RegionInfo [] mergeParents) throws IOException; + + List getFavoredNodes(RegionInfo regionInfo); } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java index 2472e34756e2..d3a4c9555c97 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java @@ -93,7 +93,6 @@ import org.apache.hadoop.hbase.exceptions.DeserializationException; import org.apache.hadoop.hbase.executor.ExecutorType; import org.apache.hadoop.hbase.favored.FavoredNodesManager; -import org.apache.hadoop.hbase.favored.FavoredNodesPromoter; import org.apache.hadoop.hbase.http.InfoServer; import org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils; import org.apache.hadoop.hbase.ipc.RpcServer; @@ -106,7 +105,6 @@ import org.apache.hadoop.hbase.master.assignment.RegionStates; import org.apache.hadoop.hbase.master.assignment.TransitRegionStateProcedure; import org.apache.hadoop.hbase.master.balancer.BalancerChore; -import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer; import org.apache.hadoop.hbase.master.balancer.ClusterStatusChore; import org.apache.hadoop.hbase.master.balancer.LoadBalancerFactory; import org.apache.hadoop.hbase.master.cleaner.DirScanPool; @@ -188,6 +186,7 @@ import org.apache.hadoop.hbase.replication.master.ReplicationLogCleaner; import org.apache.hadoop.hbase.replication.master.ReplicationPeerConfigUpgrader; import org.apache.hadoop.hbase.replication.regionserver.ReplicationStatus; +import org.apache.hadoop.hbase.rsgroup.RSGroupBasedLoadBalancer; import org.apache.hadoop.hbase.rsgroup.RSGroupInfoManager; import org.apache.hadoop.hbase.security.AccessDeniedException; import org.apache.hadoop.hbase.security.SecurityConstants; @@ -393,7 +392,7 @@ public void run() { private final LockManager lockManager = new LockManager(this); - private LoadBalancer balancer; + private RSGroupBasedLoadBalancer balancer; private RegionNormalizer normalizer; private BalancerChore balancerChore; private RegionNormalizerChore normalizerChore; @@ -450,9 +449,6 @@ public void run() { private long splitPlanCount; private long mergePlanCount; - /* Handle favored nodes information */ - private FavoredNodesManager favoredNodesManager; - /** jetty server for master to redirect requests to regionserver infoServer */ private Server masterJettyServer; @@ -790,7 +786,8 @@ public MetricsMaster getMasterMetrics() { @VisibleForTesting protected void initializeZKBasedSystemTrackers() throws IOException, InterruptedException, KeeperException, ReplicationException { - this.balancer = LoadBalancerFactory.getLoadBalancer(conf); + this.balancer = new RSGroupBasedLoadBalancer(); + this.balancer.setConf(conf); this.normalizer = RegionNormalizerFactory.getRegionNormalizer(conf); this.normalizer.setMasterServices(this); this.normalizer.setMasterRpcServices((MasterRpcServices)rpcServices); @@ -1037,9 +1034,6 @@ private void finishActiveMasterInitialization(MonitoredTask status) throws IOExc return temp; }); } - if (this.balancer instanceof FavoredNodesPromoter) { - favoredNodesManager = new FavoredNodesManager(this); - } // initialize load balancer this.balancer.setMasterServices(this); @@ -1089,11 +1083,11 @@ private void finishActiveMasterInitialization(MonitoredTask status) throws IOExc // table states messing up master launch (namespace table, etc., are not assigned). this.assignmentManager.processOfflineRegions(); // Initialize after meta is up as below scans meta - if (favoredNodesManager != null && !maintenanceMode) { + if (getFavoredNodesManager() != null && !maintenanceMode) { SnapshotOfRegionAssignmentFromMeta snapshotOfRegionAssignment = new SnapshotOfRegionAssignmentFromMeta(getConnection()); snapshotOfRegionAssignment.initialize(); - favoredNodesManager.initialize(snapshotOfRegionAssignment); + getFavoredNodesManager().initialize(snapshotOfRegionAssignment); } // set cluster status again after user regions are assigned @@ -2055,14 +2049,13 @@ public void move(final byte[] encodedRegionName, byte[] destServerName) throws I LOG.debug("Unable to determine a plan to assign " + hri); return; } - // TODO: What is this? I don't get it. - if (dest.equals(serverName) && balancer instanceof BaseLoadBalancer - && !((BaseLoadBalancer)balancer).shouldBeOnMaster(hri)) { + // TODO: deal with table on master for rs group. + if (dest.equals(serverName)) { // To avoid unnecessary region moving later by balancer. Don't put user // regions on master. - LOG.debug("Skipping move of region " + hri.getRegionNameAsString() - + " to avoid unnecessary region moving later by load balancer," - + " because it should not be on master"); + LOG.debug("Skipping move of region " + hri.getRegionNameAsString() + + " to avoid unnecessary region moving later by load balancer," + + " because it should not be on master"); return; } } @@ -3505,12 +3498,14 @@ public boolean isSplitOrMergeEnabled(MasterSwitchType switchType) { /** * Fetch the configured {@link LoadBalancer} class name. If none is set, a default is returned. - * + *

+ * Notice that, the base load balancer will always be {@link RSGroupBasedLoadBalancer} now, so + * this method will return the balancer used inside each rs group. * @return The name of the {@link LoadBalancer} in use. */ public String getLoadBalancerClassName() { - return conf.get(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, LoadBalancerFactory - .getDefaultLoadBalancerClass().getName()); + return conf.get(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, + LoadBalancerFactory.getDefaultLoadBalancerClass().getName()); } /** @@ -3525,13 +3520,13 @@ public SplitOrMergeTracker getSplitOrMergeTracker() { } @Override - public LoadBalancer getLoadBalancer() { + public RSGroupBasedLoadBalancer getLoadBalancer() { return balancer; } @Override public FavoredNodesManager getFavoredNodesManager() { - return favoredNodesManager; + return balancer.getFavoredNodesManager(); } private long executePeerProcedure(AbstractPeerProcedure procedure) throws IOException { @@ -3873,7 +3868,7 @@ public MetaRegionLocationCache getMetaRegionLocationCache() { } @Override - public RSGroupInfoManager getRSRSGroupInfoManager() { + public RSGroupInfoManager getRSGroupInfoManager() { return rsGroupInfoManager; } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java index 0fc544a6aec1..d5ca1f7d09b2 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java @@ -64,6 +64,15 @@ public interface LoadBalancer extends Configurable, Stoppable, ConfigurationObse // We deliberately use 'localhost' so the operation will fail fast ServerName BOGUS_SERVER_NAME = ServerName.valueOf("localhost,1,1"); + /** + * Config for pluggable load balancers. + * @deprecated since 3.0.0, will be removed in 4.0.0. In the new implementation, as the base load + * balancer will always be the rs group based one, you should just use + * {@link org.apache.hadoop.hbase.HConstants#HBASE_MASTER_LOADBALANCER_CLASS} to + * config the per group load balancer. + */ + @Deprecated + String HBASE_RSGROUP_LOADBALANCER_CLASS = "hbase.rsgroup.grouploadbalancer.class"; /** * Set the current cluster status. This allows a LoadBalancer to map host name to a server */ diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java index ab07bf036154..6d5a7a0cf9c1 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java @@ -76,6 +76,7 @@ import org.apache.hadoop.hbase.master.procedure.MasterProcedureUtil.NonceProcedureRunnable; import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure; import org.apache.hadoop.hbase.mob.MobUtils; +import org.apache.hadoop.hbase.net.Address; import org.apache.hadoop.hbase.procedure.MasterProcedureManager; import org.apache.hadoop.hbase.procedure2.LockType; import org.apache.hadoop.hbase.procedure2.LockedResource; @@ -230,10 +231,8 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsNormalizerEnabledResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsProcedureDoneRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsProcedureDoneResponse; -import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos - .IsSnapshotCleanupEnabledRequest; -import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos - .IsSnapshotCleanupEnabledResponse; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsSnapshotCleanupEnabledRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsSnapshotCleanupEnabledResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsSnapshotDoneRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsSnapshotDoneResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsSplitOrMergeEnabledRequest; @@ -287,10 +286,8 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetQuotaRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetQuotaResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetRegionStateInMetaRequest; -import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos - .SetSnapshotCleanupRequest; -import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos - .SetSnapshotCleanupResponse; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetSnapshotCleanupRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetSnapshotCleanupResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetSplitOrMergeEnabledRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetSplitOrMergeEnabledResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetTableStateInMetaRequest; @@ -2379,12 +2376,18 @@ public ClearDeadServersResponse clearDeadServers(RpcController controller, LOG.debug("Some dead server is still under processing, won't clear the dead server list"); response.addAllServerName(request.getServerNameList()); } else { + DeadServer deadServer = master.getServerManager().getDeadServers(); + Set

clearedServers = new HashSet<>(); for (HBaseProtos.ServerName pbServer : request.getServerNameList()) { - if (!master.getServerManager().getDeadServers() - .removeDeadServer(ProtobufUtil.toServerName(pbServer))) { + ServerName server = ProtobufUtil.toServerName(pbServer); + if (!deadServer.removeDeadServer(server)) { response.addServerName(pbServer); + } else { + clearedServers.add(server.getAddress()); } } + master.getRSGroupInfoManager().removeServers(clearedServers); + LOG.info("Remove decommissioned servers {} from RSGroup done", clearedServers); } if (master.cpHost != null) { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java index 28e254abe05a..16a3e4cde950 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java @@ -544,5 +544,5 @@ default SplitWALManager getSplitWALManager(){ /** * @return the {@link RSGroupInfoManager} */ - RSGroupInfoManager getRSRSGroupInfoManager(); + RSGroupInfoManager getRSGroupInfoManager(); } 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 0f7f396af2c8..ab473b77304f 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 @@ -72,6 +72,7 @@ import org.apache.hadoop.hbase.procedure2.ProcedureInMemoryChore; import org.apache.hadoop.hbase.procedure2.util.StringUtils; import org.apache.hadoop.hbase.regionserver.SequenceId; +import org.apache.hadoop.hbase.rsgroup.RSGroupBasedLoadBalancer; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.hadoop.hbase.util.HasThread; @@ -329,6 +330,11 @@ private LoadBalancer getBalancer() { return master.getLoadBalancer(); } + private FavoredNodesPromoter getFavoredNodePromoter() { + return (FavoredNodesPromoter) ((RSGroupBasedLoadBalancer) master.getLoadBalancer()) + .getInternalBalancer(); + } + private MasterProcedureEnv getProcedureEnvironment() { return master.getMasterProcedureExecutor().getEnvironment(); } @@ -372,7 +378,7 @@ public RegionStateStore getRegionStateStore() { public List getFavoredNodes(final RegionInfo regionInfo) { return this.shouldAssignRegionsWithFavoredNodes - ? ((FavoredStochasticBalancer) getBalancer()).getFavoredNodes(regionInfo) + ? getFavoredNodePromoter().getFavoredNodes(regionInfo) : ServerName.EMPTY_SERVER_LIST; } @@ -1833,8 +1839,8 @@ public void markRegionAsSplit(final RegionInfo parent, final ServerName serverNa regionStateStore.splitRegion(parent, daughterA, daughterB, serverName); if (shouldAssignFavoredNodes(parent)) { List onlineServers = this.master.getServerManager().getOnlineServersList(); - ((FavoredNodesPromoter)getBalancer()). - generateFavoredNodesForDaughter(onlineServers, parent, daughterA, daughterB); + getFavoredNodePromoter().generateFavoredNodesForDaughter(onlineServers, parent, daughterA, + daughterB); } } @@ -1859,8 +1865,7 @@ public void markRegionAsMerged(final RegionInfo child, final ServerName serverNa } regionStateStore.mergeRegions(child, mergeParents, serverName); if (shouldAssignFavoredNodes(child)) { - ((FavoredNodesPromoter)getBalancer()). - generateFavoredNodesForMergedRegion(child, mergeParents); + getFavoredNodePromoter().generateFavoredNodesForMergedRegion(child, mergeParents); } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/FavoredStochasticBalancer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/FavoredStochasticBalancer.java index 1daa9e71c8bc..442dc443021e 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/FavoredStochasticBalancer.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/FavoredStochasticBalancer.java @@ -473,6 +473,7 @@ private List getOnlineFavoredNodes(List onlineServers, } } + @Override public synchronized List getFavoredNodes(RegionInfo regionInfo) { return this.fnm.getFavoredNodes(regionInfo); } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/LoadBalancerFactory.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/LoadBalancerFactory.java index 9ce020be4568..bfda12e335cb 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/LoadBalancerFactory.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/LoadBalancerFactory.java @@ -17,11 +17,11 @@ */ package org.apache.hadoop.hbase.master.balancer; -import org.apache.yetus.audience.InterfaceAudience; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.master.LoadBalancer; -import org.apache.hadoop.util.ReflectionUtils; +import org.apache.hadoop.hbase.util.ReflectionUtils; +import org.apache.yetus.audience.InterfaceAudience; /** * The class that creates a load balancer from a conf. @@ -30,8 +30,7 @@ public class LoadBalancerFactory { /** - * The default {@link LoadBalancer} class. - * + * The default {@link LoadBalancer} class. * @return The Class for the default {@link LoadBalancer}. */ public static Class getDefaultLoadBalancerClass() { @@ -40,16 +39,15 @@ public static Class getDefaultLoadBalancerClass() { /** * Create a loadbalancer from the given conf. - * @param conf * @return A {@link LoadBalancer} */ public static LoadBalancer getLoadBalancer(Configuration conf) { - // Create the balancer Class balancerKlass = - conf.getClass(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, getDefaultLoadBalancerClass(), - LoadBalancer.class); - return ReflectionUtils.newInstance(balancerKlass, conf); - + conf.getClass(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, getDefaultLoadBalancerClass(), + LoadBalancer.class); + LoadBalancer balancer = ReflectionUtils.newInstance(balancerKlass); + balancer.setConf(conf); + return balancer; } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/AbstractStateMachineNamespaceProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/AbstractStateMachineNamespaceProcedure.java index e751034e2e0a..5c35544589ed 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/AbstractStateMachineNamespaceProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/AbstractStateMachineNamespaceProcedure.java @@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.master.procedure; import java.io.IOException; +import java.util.function.Supplier; import org.apache.hadoop.hbase.NamespaceDescriptor; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.master.MasterFileSystem; @@ -28,6 +29,7 @@ import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.hadoop.hbase.procedure2.StateMachineProcedure; +import org.apache.hadoop.hbase.rsgroup.RSGroupInfo; import org.apache.hadoop.hbase.util.FSUtils; /** @@ -122,4 +124,13 @@ public static void createDirectory(MasterFileSystem mfs, NamespaceDescriptor nsD protected void releaseSyncLatch() { ProcedurePrepareLatch.releaseLatch(syncLatch, this); } + + protected final void checkNamespaceRSGroup(MasterProcedureEnv env, NamespaceDescriptor nd) + throws IOException { + Supplier forWhom = () -> "namespace " + nd.getName(); + RSGroupInfo rsGroupInfo = MasterProcedureUtil.checkGroupExists( + env.getMasterServices().getRSGroupInfoManager()::getRSGroup, + MasterProcedureUtil.getNamespaceGroup(nd), forWhom); + MasterProcedureUtil.checkGroupNotEmpty(rsGroupInfo, forWhom); + } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateNamespaceProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateNamespaceProcedure.java index 28f75859c8c6..bc603609eb5d 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateNamespaceProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateNamespaceProcedure.java @@ -188,6 +188,7 @@ private boolean prepareCreate(final MasterProcedureEnv env) throws IOException { return false; } getTableNamespaceManager(env).validateTableAndRegionCount(nsDescriptor); + checkNamespaceRSGroup(env, nsDescriptor); return true; } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java index a6c96a37e9ef..2fb303fe93ca 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java @@ -21,11 +21,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; - +import java.util.function.Supplier; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.DoNotRetryIOException; import org.apache.hadoop.hbase.MetaTableAccessor; +import org.apache.hadoop.hbase.NamespaceDescriptor; import org.apache.hadoop.hbase.TableExistsException; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.RegionInfo; @@ -35,6 +36,7 @@ import org.apache.hadoop.hbase.master.MasterCoprocessorHost; import org.apache.hadoop.hbase.master.MasterFileSystem; import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer; +import org.apache.hadoop.hbase.rsgroup.RSGroupInfo; import org.apache.hadoop.hbase.util.FSTableDescriptors; import org.apache.hadoop.hbase.util.FSUtils; import org.apache.hadoop.hbase.util.ModifyRegionUtils; @@ -42,8 +44,10 @@ import org.apache.yetus.audience.InterfaceAudience; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.hbase.thirdparty.com.google.common.collect.Lists; + import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos; @@ -252,10 +256,27 @@ private boolean prepareCreate(final MasterProcedureEnv env) throws IOException { // check that we have at least 1 CF if (tableDescriptor.getColumnFamilyCount() == 0) { - setFailure("master-create-table", new DoNotRetryIOException("Table " + - getTableName().toString() + " should have at least one column family.")); + setFailure("master-create-table", new DoNotRetryIOException( + "Table " + getTableName().toString() + " should have at least one column family.")); return false; } + if (!tableName.isSystemTable()) { + // do not check rs group for system tables as we may block the bootstrap. + Supplier forWhom = () -> "table " + tableName; + RSGroupInfo rsGroupInfo = MasterProcedureUtil.checkGroupExists( + env.getMasterServices().getRSGroupInfoManager()::getRSGroup, + tableDescriptor.getRegionServerGroup(), forWhom); + if (rsGroupInfo == null) { + // we do not set rs group info on table, check if we have one on namespace + String namespace = tableName.getNamespaceAsString(); + NamespaceDescriptor nd = env.getMasterServices().getClusterSchema().getNamespace(namespace); + forWhom = () -> "table " + tableName + "(inherit from namespace)"; + rsGroupInfo = MasterProcedureUtil.checkGroupExists( + env.getMasterServices().getRSGroupInfoManager()::getRSGroup, + MasterProcedureUtil.getNamespaceGroup(nd), forWhom); + } + MasterProcedureUtil.checkGroupNotEmpty(rsGroupInfo, forWhom); + } return true; } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/MasterProcedureUtil.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/MasterProcedureUtil.java index 49bf5c85322e..111c4fe1b068 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/MasterProcedureUtil.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/MasterProcedureUtil.java @@ -18,14 +18,18 @@ package org.apache.hadoop.hbase.master.procedure; import java.io.IOException; +import java.util.Optional; +import java.util.function.Supplier; import java.util.regex.Pattern; - import org.apache.hadoop.hbase.DoNotRetryIOException; +import org.apache.hadoop.hbase.NamespaceDescriptor; import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.constraint.ConstraintException; import org.apache.hadoop.hbase.master.MasterServices; import org.apache.hadoop.hbase.procedure2.Procedure; import org.apache.hadoop.hbase.procedure2.ProcedureException; import org.apache.hadoop.hbase.procedure2.ProcedureExecutor; +import org.apache.hadoop.hbase.rsgroup.RSGroupInfo; import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.util.NonceKey; import org.apache.hadoop.security.UserGroupInformation; @@ -192,10 +196,52 @@ public static int getServerPriority(ServerProcedureInterface proc) { * keep trying. The default proc.getException().unwrapRemoteException * doesn't have access to DNRIOE from the procedure2 module. */ - public static IOException unwrapRemoteIOException(Procedure proc) { + public static IOException unwrapRemoteIOException(Procedure proc) { Exception e = proc.getException().unwrapRemoteException(); // Do not retry ProcedureExceptions! return (e instanceof ProcedureException)? new DoNotRetryIOException(e): proc.getException().unwrapRemoteIOException(); } + + /** + * Do not allow creating new tables/namespaces which has an empty rs group, expect the default rs + * group. Notice that we do not check for online servers, as this is not stable because region + * servers can die at any time. + */ + public static void checkGroupNotEmpty(RSGroupInfo rsGroupInfo, Supplier forWhom) + throws ConstraintException { + if (rsGroupInfo == null || rsGroupInfo.getName().equals(RSGroupInfo.DEFAULT_GROUP)) { + // we do not have a rs group config or we explicitly set the rs group to default, then no need + // to check. + return; + } + if (rsGroupInfo.getServers().isEmpty()) { + throw new ConstraintException( + "No servers in the rsgroup " + rsGroupInfo.getName() + " for " + forWhom.get()); + } + } + + @FunctionalInterface + public interface RSGroupGetter { + RSGroupInfo get(String groupName) throws IOException; + } + + public static RSGroupInfo checkGroupExists(RSGroupGetter getter, Optional optGroupName, + Supplier forWhom) throws IOException { + if (optGroupName.isPresent()) { + String groupName = optGroupName.get(); + RSGroupInfo group = getter.get(groupName); + if (group == null) { + throw new ConstraintException( + "Region server group " + groupName + " for " + forWhom.get() + " does not exit"); + } + return group; + } + return null; + } + + public static Optional getNamespaceGroup(NamespaceDescriptor namespaceDesc) { + return Optional + .ofNullable(namespaceDesc.getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP)); + } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ModifyNamespaceProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ModifyNamespaceProcedure.java index e3327e200c9c..c52b93d5dd6b 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ModifyNamespaceProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ModifyNamespaceProcedure.java @@ -18,10 +18,11 @@ package org.apache.hadoop.hbase.master.procedure; import java.io.IOException; +import java.util.Objects; import org.apache.hadoop.hbase.NamespaceDescriptor; import org.apache.hadoop.hbase.NamespaceNotFoundException; -import org.apache.hadoop.hbase.constraint.ConstraintException; import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer; +import org.apache.hadoop.hbase.rsgroup.RSGroupInfo; import org.apache.yetus.audience.InterfaceAudience; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -171,24 +172,22 @@ protected String getNamespaceName() { /** * Action before any real action of adding namespace. - * @param env MasterProcedureEnv - * @throws IOException */ private boolean prepareModify(final MasterProcedureEnv env) throws IOException { - if (getTableNamespaceManager(env).doesNamespaceExist(newNsDescriptor.getName()) == false) { + if (!getTableNamespaceManager(env).doesNamespaceExist(newNsDescriptor.getName())) { setFailure("master-modify-namespace", new NamespaceNotFoundException(newNsDescriptor.getName())); return false; } - try { - getTableNamespaceManager(env).validateTableAndRegionCount(newNsDescriptor); - } catch (ConstraintException e) { - setFailure("master-modify-namespace", e); - return false; - } + getTableNamespaceManager(env).validateTableAndRegionCount(newNsDescriptor); // This is used for rollback oldNsDescriptor = getTableNamespaceManager(env).get(newNsDescriptor.getName()); + if (!Objects.equals( + oldNsDescriptor.getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP), + newNsDescriptor.getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP))) { + checkNamespaceRSGroup(env, newNsDescriptor); + } return true; } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ModifyTableProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ModifyTableProcedure.java index f90e06b2c200..49b04e4293aa 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ModifyTableProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ModifyTableProcedure.java @@ -24,7 +24,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; - +import java.util.function.Supplier; import org.apache.hadoop.hbase.ConcurrentTableModificationException; import org.apache.hadoop.hbase.DoNotRetryIOException; import org.apache.hadoop.hbase.HBaseIOException; @@ -43,6 +43,7 @@ import org.apache.hadoop.hbase.client.TableState; import org.apache.hadoop.hbase.master.MasterCoprocessorHost; import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer; +import org.apache.hadoop.hbase.rsgroup.RSGroupInfo; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.ServerRegionReplicaUtil; import org.apache.yetus.audience.InterfaceAudience; @@ -270,8 +271,6 @@ public TableOperationType getTableOperationType() { /** * Check conditions before any real action of modifying a table. - * @param env MasterProcedureEnv - * @throws IOException */ private void prepareModify(final MasterProcedureEnv env) throws IOException { // Checks whether the table exists @@ -314,6 +313,14 @@ private void prepareModify(final MasterProcedureEnv env) throws IOException { } this.deleteColumnFamilyInModify = isDeleteColumnFamily(unmodifiedTableDescriptor, modifiedTableDescriptor); + if (!unmodifiedTableDescriptor.getRegionServerGroup() + .equals(modifiedTableDescriptor.getRegionServerGroup())) { + Supplier forWhom = () -> "table " + getTableName(); + RSGroupInfo rsGroupInfo = MasterProcedureUtil.checkGroupExists( + env.getMasterServices().getRSGroupInfoManager()::getRSGroup, + modifiedTableDescriptor.getRegionServerGroup(), forWhom); + MasterProcedureUtil.checkGroupNotEmpty(rsGroupInfo, forWhom); + } } /** diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java index 0bde67b77596..353b4d2f0348 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java @@ -20,38 +20,25 @@ import com.google.protobuf.Service; import java.io.IOException; import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.function.Supplier; -import java.util.stream.Collectors; import org.apache.hadoop.hbase.CoprocessorEnvironment; -import org.apache.hadoop.hbase.HConstants; -import org.apache.hadoop.hbase.NamespaceDescriptor; -import org.apache.hadoop.hbase.ServerName; -import org.apache.hadoop.hbase.TableName; -import org.apache.hadoop.hbase.client.RegionInfo; -import org.apache.hadoop.hbase.client.TableDescriptor; -import org.apache.hadoop.hbase.constraint.ConstraintException; import org.apache.hadoop.hbase.coprocessor.CoreCoprocessor; import org.apache.hadoop.hbase.coprocessor.HasMasterServices; import org.apache.hadoop.hbase.coprocessor.MasterCoprocessor; -import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment; -import org.apache.hadoop.hbase.coprocessor.MasterObserver; -import org.apache.hadoop.hbase.coprocessor.ObserverContext; import org.apache.hadoop.hbase.master.MasterServices; -import org.apache.hadoop.hbase.net.Address; import org.apache.hadoop.hbase.security.UserProvider; import org.apache.hadoop.hbase.security.access.AccessChecker; import org.apache.yetus.audience.InterfaceAudience; import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; -// TODO: Encapsulate MasterObserver functions into separate subclass. +/** + * @deprecated Keep it here only for compatibility with old client, all the logics have been moved + * into core of HBase. + */ +@Deprecated @CoreCoprocessor @InterfaceAudience.Private -public class RSGroupAdminEndpoint implements MasterCoprocessor, MasterObserver { +public class RSGroupAdminEndpoint implements MasterCoprocessor { // Only instance of RSGroupInfoManager. RSGroup aware load balancers ask for this instance on // their setup. private MasterServices master; @@ -66,13 +53,8 @@ public void start(CoprocessorEnvironment env) throws IOException { } master = ((HasMasterServices) env).getMasterServices(); - groupInfoManager = master.getRSRSGroupInfoManager(); + groupInfoManager = master.getRSGroupInfoManager(); groupAdminServer = new RSGroupAdminServer(master, groupInfoManager); - Class clazz = - master.getConfiguration().getClass(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, null); - if (!RSGroupableBalancer.class.isAssignableFrom(clazz)) { - throw new IOException("Configured balancer does not support RegionServer groups."); - } AccessChecker accessChecker = ((HasMasterServices) env).getMasterServices().getAccessChecker(); // set the user-provider. @@ -89,11 +71,6 @@ public Iterable getServices() { return Collections.singleton(groupAdminService); } - @Override - public Optional getMasterObserver() { - return Optional.of(this); - } - RSGroupInfoManager getGroupInfoManager() { return groupInfoManager; } @@ -102,108 +79,4 @@ RSGroupInfoManager getGroupInfoManager() { RSGroupAdminServiceImpl getGroupAdminService() { return groupAdminService; } - - ///////////////////////////////////////////////////////////////////////////// - // MasterObserver overrides - ///////////////////////////////////////////////////////////////////////////// - - @Override - public void postClearDeadServers(ObserverContext ctx, - List servers, List notClearedServers) throws IOException { - Set
clearedServer = - servers.stream().filter(server -> !notClearedServers.contains(server)) - .map(ServerName::getAddress).collect(Collectors.toSet()); - if (!clearedServer.isEmpty()) { - groupAdminServer.removeServers(clearedServer); - } - } - - private RSGroupInfo checkGroupExists(Optional optGroupName, Supplier forWhom) - throws IOException { - if (optGroupName.isPresent()) { - String groupName = optGroupName.get(); - RSGroupInfo group = groupAdminServer.getRSGroupInfo(groupName); - if (group == null) { - throw new ConstraintException( - "Region server group " + groupName + " for " + forWhom.get() + " does not exit"); - } - return group; - } - return null; - } - - private Optional getNamespaceGroup(NamespaceDescriptor namespaceDesc) { - return Optional - .ofNullable(namespaceDesc.getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP)); - } - - // Do not allow creating new tables/namespaces which has an empty rs group, expect the default rs - // group. Notice that we do not check for online servers, as this is not stable because region - // servers can die at any time. - private void checkGroupNotEmpty(RSGroupInfo rsGroupInfo, Supplier forWhom) - throws ConstraintException { - if (rsGroupInfo == null || rsGroupInfo.getName().equals(RSGroupInfo.DEFAULT_GROUP)) { - // we do not have a rs group config or we explicitly set the rs group to default, then no need - // to check. - return; - } - if (rsGroupInfo.getServers().isEmpty()) { - throw new ConstraintException( - "No servers in the rsgroup " + rsGroupInfo.getName() + " for " + forWhom.get()); - } - } - - @Override - public void preCreateTableAction(ObserverContext ctx, - TableDescriptor desc, RegionInfo[] regions) throws IOException { - if (desc.getTableName().isSystemTable()) { - // do not check for system tables as we may block the bootstrap. - return; - } - Supplier forWhom = () -> "table " + desc.getTableName(); - RSGroupInfo rsGroupInfo = checkGroupExists(desc.getRegionServerGroup(), forWhom); - if (rsGroupInfo == null) { - // we do not set rs group info on table, check if we have one on namespace - String namespace = desc.getTableName().getNamespaceAsString(); - NamespaceDescriptor nd = master.getClusterSchema().getNamespace(namespace); - forWhom = () -> "table " + desc.getTableName() + "(inherit from namespace)"; - rsGroupInfo = checkGroupExists(getNamespaceGroup(nd), forWhom); - } - checkGroupNotEmpty(rsGroupInfo, forWhom); - } - - @Override - public TableDescriptor preModifyTable(ObserverContext ctx, - TableName tableName, TableDescriptor currentDescriptor, TableDescriptor newDescriptor) - throws IOException { - if (!currentDescriptor.getRegionServerGroup().equals(newDescriptor.getRegionServerGroup())) { - Supplier forWhom = () -> "table " + newDescriptor.getTableName(); - RSGroupInfo rsGroupInfo = checkGroupExists(newDescriptor.getRegionServerGroup(), forWhom); - checkGroupNotEmpty(rsGroupInfo, forWhom); - } - return MasterObserver.super.preModifyTable(ctx, tableName, currentDescriptor, newDescriptor); - } - - private void checkNamespaceGroup(NamespaceDescriptor nd) throws IOException { - Supplier forWhom = () -> "namespace " + nd.getName(); - RSGroupInfo rsGroupInfo = checkGroupExists(getNamespaceGroup(nd), forWhom); - checkGroupNotEmpty(rsGroupInfo, forWhom); - } - - @Override - public void preCreateNamespace(ObserverContext ctx, - NamespaceDescriptor ns) throws IOException { - checkNamespaceGroup(ns); - } - - @Override - public void preModifyNamespace(ObserverContext ctx, - NamespaceDescriptor currentNsDescriptor, NamespaceDescriptor newNsDescriptor) - throws IOException { - if (!Objects.equals( - currentNsDescriptor.getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP), - newNsDescriptor.getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP))) { - checkNamespaceGroup(newNsDescriptor); - } - } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupBasedLoadBalancer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupBasedLoadBalancer.java index 0f943d078c41..fb3db84f46c3 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupBasedLoadBalancer.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupBasedLoadBalancer.java @@ -35,13 +35,15 @@ import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.RegionInfo; import org.apache.hadoop.hbase.constraint.ConstraintException; +import org.apache.hadoop.hbase.favored.FavoredNodesManager; +import org.apache.hadoop.hbase.favored.FavoredNodesPromoter; import org.apache.hadoop.hbase.master.LoadBalancer; import org.apache.hadoop.hbase.master.MasterServices; import org.apache.hadoop.hbase.master.RegionPlan; -import org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer; +import org.apache.hadoop.hbase.master.balancer.LoadBalancerFactory; import org.apache.hadoop.hbase.net.Address; import org.apache.hadoop.hbase.util.Pair; -import org.apache.hadoop.util.ReflectionUtils; +import org.apache.hadoop.hbase.util.ReflectionUtils; import org.apache.yetus.audience.InterfaceAudience; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,12 +69,13 @@ * providing appropriate assignments for user tables. */ @InterfaceAudience.Private -public class RSGroupBasedLoadBalancer implements RSGroupableBalancer { +public class RSGroupBasedLoadBalancer implements LoadBalancer { private static final Logger LOG = LoggerFactory.getLogger(RSGroupBasedLoadBalancer.class); private Configuration config; private ClusterMetrics clusterStatus; private MasterServices masterServices; + private FavoredNodesManager favoredNodesManager; private volatile RSGroupInfoManager rsGroupInfoManager; private LoadBalancer internalBalancer; @@ -330,36 +333,42 @@ private Pair>, List> correctAssignm @Override public void initialize() throws IOException { - try { + if (rsGroupInfoManager == null) { + rsGroupInfoManager = masterServices.getRSGroupInfoManager(); if (rsGroupInfoManager == null) { - List cps = - masterServices.getMasterCoprocessorHost().findCoprocessors(RSGroupAdminEndpoint.class); - if (cps.size() != 1) { - String msg = "Expected one implementation of GroupAdminEndpoint but found " + cps.size(); - LOG.error(msg); - throw new HBaseIOException(msg); - } - rsGroupInfoManager = cps.get(0).getGroupInfoManager(); - if(rsGroupInfoManager == null){ - String msg = "RSGroupInfoManager hasn't been initialized"; - LOG.error(msg); - throw new HBaseIOException(msg); - } - rsGroupInfoManager.start(); + String msg = "RSGroupInfoManager hasn't been initialized"; + LOG.error(msg); + throw new HBaseIOException(msg); } - } catch (IOException e) { - throw new HBaseIOException("Failed to initialize GroupInfoManagerImpl", e); + rsGroupInfoManager.start(); } // Create the balancer - Class balancerKlass = config.getClass(HBASE_RSGROUP_LOADBALANCER_CLASS, - StochasticLoadBalancer.class, LoadBalancer.class); - internalBalancer = ReflectionUtils.newInstance(balancerKlass, config); + Class balancerClass; + String balancerClassName = config.get(HBASE_RSGROUP_LOADBALANCER_CLASS); + if (balancerClassName == null) { + balancerClass = config.getClass(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, + LoadBalancerFactory.getDefaultLoadBalancerClass(), LoadBalancer.class); + } else { + try { + balancerClass = Class.forName(balancerClassName).asSubclass(LoadBalancer.class); + } catch (ClassNotFoundException e) { + throw new IOException(e); + } + } + // avoid infinite nesting + if (getClass().isAssignableFrom(balancerClass)) { + balancerClass = LoadBalancerFactory.getDefaultLoadBalancerClass(); + } + internalBalancer = ReflectionUtils.newInstance(balancerClass); + if (internalBalancer instanceof FavoredNodesPromoter) { + favoredNodesManager = new FavoredNodesManager(masterServices); + } + internalBalancer.setConf(config); internalBalancer.setMasterServices(masterServices); if(clusterStatus != null) { internalBalancer.setClusterMetrics(clusterStatus); } - internalBalancer.setConf(config); internalBalancer.initialize(); } @@ -402,6 +411,14 @@ public void setRsGroupInfoManager(RSGroupInfoManager rsGroupInfoManager) { this.rsGroupInfoManager = rsGroupInfoManager; } + public LoadBalancer getInternalBalancer() { + return internalBalancer; + } + + public FavoredNodesManager getFavoredNodesManager() { + return favoredNodesManager; + } + @Override public void postMasterStartupInitialize() { this.internalBalancer.postMasterStartupInitialize(); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java index 7224869192b4..ce0bd8cc1574 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java @@ -427,7 +427,7 @@ private void migrate(Collection groupList) { // master first and then region server, so after all the region servers has been reopened, // the new TableDescriptor will be loaded. try { - tds.add(newTd); + tds.update(newTd); } catch (IOException e) { LOG.warn("Failed to migrate {} in group {}", tableName, groupInfo.getName(), e); failedTables.add(tableName); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupableBalancer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupableBalancer.java deleted file mode 100644 index d091b3cfbdef..000000000000 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupableBalancer.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hadoop.hbase.rsgroup; - -import org.apache.hadoop.hbase.master.LoadBalancer; -import org.apache.yetus.audience.InterfaceAudience; - -/** - * Marker Interface. RSGroups feature will check for a LoadBalancer - * marked with this Interface before it runs. - */ -@InterfaceAudience.Private -public interface RSGroupableBalancer extends LoadBalancer { - /** Config for pluggable load balancers */ - String HBASE_RSGROUP_LOADBALANCER_CLASS = "hbase.rsgroup.grouploadbalancer.class"; -} diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestNamespace.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestNamespace.java index 9f74aa44a806..df161c9853ad 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestNamespace.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestNamespace.java @@ -118,7 +118,7 @@ public void verifyReservedNS() throws IOException { //verify existence of system tables Set systemTables = Sets.newHashSet( - TableName.META_TABLE_NAME); + TableName.META_TABLE_NAME, TableName.valueOf("hbase:rsgroup")); List descs = admin.listTableDescriptorsByNamespace( Bytes.toBytes(NamespaceDescriptor.SYSTEM_NAMESPACE.getName())); assertEquals(systemTables.size(), descs.size()); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/AbstractTestDLS.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/AbstractTestDLS.java index a576adc8d192..fc2e9f79c380 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/AbstractTestDLS.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/AbstractTestDLS.java @@ -504,14 +504,14 @@ private Table installTable(int nrs, int existingRegions) throws Exception { for (String oregion : regions) LOG.debug("Region still online: " + oregion); } - assertEquals(1 + existingRegions, regions.size()); + assertEquals(2 + existingRegions, regions.size()); LOG.debug("Enabling table\n"); TEST_UTIL.getAdmin().enableTable(tableName); LOG.debug("Waiting for no more RIT\n"); blockUntilNoRIT(); LOG.debug("Verifying there are " + numRegions + " assigned on cluster\n"); regions = HBaseTestingUtility.getAllOnlineRegions(cluster); - assertEquals(numRegions + 1 + existingRegions, regions.size()); + assertEquals(numRegions + 2 + existingRegions, regions.size()); return table; } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/MockNoopMasterServices.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/MockNoopMasterServices.java index cde6ea0a716a..5554e515a21c 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/MockNoopMasterServices.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/MockNoopMasterServices.java @@ -497,7 +497,7 @@ public void runReplicationBarrierCleaner() { } @Override - public RSGroupInfoManager getRSRSGroupInfoManager() { + public RSGroupInfoManager getRSGroupInfoManager() { return null; } } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestClusterRestart.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestClusterRestart.java index 5a3823485e45..a8d80b6068da 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestClusterRestart.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestClusterRestart.java @@ -43,6 +43,8 @@ public class TestClusterRestart extends AbstractTestRestartCluster { private static final Logger LOG = LoggerFactory.getLogger(TestClusterRestart.class); + private static final int NUM_REGIONS = 4; + @Override protected boolean splitWALCoordinatedByZk() { return true; @@ -61,7 +63,7 @@ public void test() throws Exception { } List allRegions = MetaTableAccessor.getAllRegions(UTIL.getConnection(), false); - assertEquals(3, allRegions.size()); + assertEquals(NUM_REGIONS, allRegions.size()); LOG.info("\n\nShutting down cluster"); UTIL.shutdownMiniHBaseCluster(); @@ -76,7 +78,7 @@ public void test() throws Exception { // Otherwise we're reusing an Connection that has gone stale because // the shutdown of the cluster also called shut of the connection. allRegions = MetaTableAccessor.getAllRegions(UTIL.getConnection(), false); - assertEquals(3, allRegions.size()); + assertEquals(NUM_REGIONS, allRegions.size()); LOG.info("\n\nWaiting for tables to be available"); for (TableName TABLE : TABLES) { try { diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java index 75d9ee199b96..61720df33f27 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java @@ -25,6 +25,7 @@ import org.apache.hadoop.hbase.MiniHBaseCluster; import org.apache.hadoop.hbase.ServerName; import org.apache.hadoop.hbase.StartMiniClusterOption; +import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.test.MetricsAssertHelper; import org.apache.hadoop.hbase.testclassification.MasterTests; import org.apache.hadoop.hbase.testclassification.MediumTests; @@ -90,6 +91,7 @@ public static void startCluster() throws Exception { cluster = TEST_UTIL.getHBaseCluster(); LOG.info("Waiting for active/ready master"); cluster.waitForActiveAndReadyMaster(); + TEST_UTIL.waitTableAvailable(TableName.valueOf("hbase:rsgroup")); master = cluster.getMaster(); } @@ -131,7 +133,7 @@ public void testDefaultMasterMetrics() throws Exception { MetricsMasterSource masterSource = master.getMasterMetrics().getMetricsSource(); boolean tablesOnMaster = LoadBalancer.isTablesOnMaster(TEST_UTIL.getConfiguration()); metricsHelper.assertGauge("numRegionServers", 1 + (tablesOnMaster ? 1 : 0), masterSource); - metricsHelper.assertGauge("averageLoad", 1, masterSource); + metricsHelper.assertGauge("averageLoad", 2, masterSource); metricsHelper.assertGauge("numDeadRegionServers", 0, masterSource); metricsHelper.assertGauge("masterStartTime", master.getMasterStartTime(), masterSource); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterRestartAfterDisablingTable.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterRestartAfterDisablingTable.java index fca2866e3802..2d0af3e9750e 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterRestartAfterDisablingTable.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterRestartAfterDisablingTable.java @@ -92,7 +92,7 @@ public void testForCheckingIfEnableAndDisableWorksFineAfterSwitch() NavigableSet regions = HBaseTestingUtility.getAllOnlineRegions(cluster); assertEquals("The number of regions for the table tableRestart should be 0 and only" + - "the catalog table should be present.", 1, regions.size()); + "the catalog table should be present.", 2, regions.size()); List masterThreads = cluster.getMasterThreads(); MasterThread activeMaster = null; @@ -120,7 +120,7 @@ public void testForCheckingIfEnableAndDisableWorksFineAfterSwitch() log("Verifying there are " + numRegions + " assigned on cluster\n"); regions = HBaseTestingUtility.getAllOnlineRegions(cluster); assertEquals("The assigned regions were not onlined after master" + - " switch except for the catalog table.", 5, regions.size()); + " switch except for the catalog table.", 6, regions.size()); assertTrue("The table should be in enabled state", cluster.getMaster().getTableStateManager() .isTableState(TableName.valueOf(name.getMethodName()), TableState.State.ENABLED)); ht.close(); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestRollingRestart.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestRollingRestart.java index 0aba48747829..2dc1b6c7a0e2 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestRollingRestart.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestRollingRestart.java @@ -121,7 +121,7 @@ public void testBasicRollingRestart() throws Exception { log("Region still online: " + oregion); } } - assertEquals(1, regions.size()); + assertEquals(2, regions.size()); log("Enabling table\n"); TEST_UTIL.getAdmin().enableTable(tableName); log("Waiting for no more RIT\n"); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestFavoredStochasticBalancerPickers.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestFavoredStochasticBalancerPickers.java index 0aa232205b00..7677eb633d54 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestFavoredStochasticBalancerPickers.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestFavoredStochasticBalancerPickers.java @@ -186,7 +186,7 @@ public boolean evaluate() throws Exception { regionFinder.setServices(TEST_UTIL.getMiniHBaseCluster().getMaster()); Cluster cluster = new Cluster(serverAssignments, null, regionFinder, new RackManager(conf)); LoadOnlyFavoredStochasticBalancer balancer = (LoadOnlyFavoredStochasticBalancer) TEST_UTIL - .getMiniHBaseCluster().getMaster().getLoadBalancer(); + .getMiniHBaseCluster().getMaster().getLoadBalancer().getInternalBalancer(); cluster.sortServersByRegionCount(); Integer[] servers = cluster.serverIndicesSortedByRegionCount; diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionOpen.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionOpen.java index 7ab5dcc76550..2503825a2189 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionOpen.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionOpen.java @@ -59,7 +59,6 @@ public class TestRegionOpen { public static final HBaseClassTestRule CLASS_RULE = HBaseClassTestRule.forClass(TestRegionOpen.class); - @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(TestRegionOpen.class); private static final int NB_SERVERS = 1; @@ -87,6 +86,7 @@ public void testPriorityRegionIsOpenedWithSeparateThreadPool() throws Exception final TableName tableName = TableName.valueOf(TestRegionOpen.class.getSimpleName()); ThreadPoolExecutor exec = getRS().getExecutorService() .getExecutorThreadPool(ExecutorType.RS_OPEN_PRIORITY_REGION); + HTU.waitTableAvailable(TableName.valueOf("hbase:rsgroup")); long completed = exec.getCompletedTaskCount(); HTableDescriptor htd = new HTableDescriptor(tableName); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionReplicasWithRestartScenarios.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionReplicasWithRestartScenarios.java index d4e250708e2e..6211db680b63 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionReplicasWithRestartScenarios.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionReplicasWithRestartScenarios.java @@ -156,7 +156,7 @@ private void assertReplicaDistributed(Collection onlineRegions) throws assertFalse(res); int totalRegions = HTU.getMiniHBaseCluster().getLiveRegionServerThreads().stream(). mapToInt(l -> l.getRegionServer().getOnlineRegions().size()).sum(); - assertEquals(61, totalRegions); + assertEquals(62, totalRegions); } private boolean checkDuplicates(Collection onlineRegions3) throws Exception { diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionServerMetrics.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionServerMetrics.java index 833e78ba3b0e..8361d58de001 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionServerMetrics.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionServerMetrics.java @@ -231,7 +231,7 @@ private void doScan(int n, boolean caching) throws IOException { @Test public void testRegionCount() throws Exception { - metricsHelper.assertGauge("regionCount", TABLES_ON_MASTER ? 1 : 2, serverSource); + metricsHelper.assertGauge("regionCount", TABLES_ON_MASTER ? 1 : 3, serverSource); } @Test @@ -341,7 +341,7 @@ public void testStoreCount() throws Exception { TEST_UTIL.getAdmin().flush(tableName); metricsRegionServer.getRegionServerWrapper().forceRecompute(); - assertGauge("storeCount", TABLES_ON_MASTER ? 1 : 5); + assertGauge("storeCount", TABLES_ON_MASTER ? 1 : 6); assertGauge("storeFileCount", 1); } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsOfflineMode.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsOfflineMode.java index d3577f24e73d..7ac1a49fda5b 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsOfflineMode.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsOfflineMode.java @@ -163,8 +163,7 @@ public boolean evaluate() throws Exception { }); // Get groupInfoManager from the new active master. - RSGroupInfoManager groupMgr = ((MiniHBaseCluster) cluster).getMaster() - .getMasterCoprocessorHost().findCoprocessor(RSGroupAdminEndpoint.class).getGroupInfoManager(); + RSGroupInfoManager groupMgr = ((MiniHBaseCluster) cluster).getMaster().getRSGroupInfoManager(); // Make sure balancer is in offline mode, since this is what we're testing. assertFalse(groupMgr.isOnline()); // Kill final regionserver to see the failover happens for all tables except GROUP table since diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestTablePermissions.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestTablePermissions.java index 078e065ce016..3de38a7fc4c7 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestTablePermissions.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestTablePermissions.java @@ -102,6 +102,7 @@ public static void beforeClass() throws Exception { // Wait for the ACL table to become available UTIL.waitTableEnabled(PermissionStorage.ACL_TABLE_NAME); + UTIL.waitTableAvailable(TableName.valueOf("hbase:rsgroup")); ZKW = new ZKWatcher(UTIL.getConfiguration(), "TestTablePermissions", ABORTABLE); @@ -222,7 +223,7 @@ public void testBasicWrite() throws Exception { // check full load Map> allPerms = PermissionStorage.loadAll(conf); assertEquals("Full permission map should have entries for both test tables", - 2, allPerms.size()); + 3, allPerms.size()); userPerms = allPerms.get(TEST_TABLE.getName()).get("hubert"); assertNotNull(userPerms); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsckReplication.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsckReplication.java index 316a321f2b7b..0ac07d869aa9 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsckReplication.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsckReplication.java @@ -24,6 +24,7 @@ import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.ServerName; +import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.replication.ReplicationPeerConfig; import org.apache.hadoop.hbase.replication.ReplicationPeerStorage; import org.apache.hadoop.hbase.replication.ReplicationQueueStorage; @@ -52,6 +53,7 @@ public class TestHBaseFsckReplication { public static void setUp() throws Exception { UTIL.getConfiguration().setBoolean("hbase.write.hbck1.lock.file", false); UTIL.startMiniCluster(1); + UTIL.waitTableAvailable(TableName.valueOf("hbase:rsgroup")); } @AfterClass